以下の関数名 __construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone() および __debugInfo() は、PHP クラスにおける特殊関数の名前です。 これらの関数に関連する特別な機能を使用する場合を除き、 クラス内にこれらの名前を有する関数を作成してはいけません。
PHP は、__ で始まる関数名を特殊関数として予約しています。 文書化された特殊な機能を必要とする場合を除き、 __ で始まる関数名を使用しないことが推奨されます。
serialize() は、クラスに特殊な名前
__sleep() の関数があるかどうかを調べます。
もしあれば、シリアル化の前にその関数を実行します。
この関数で、オブジェクトをクリアすることができます。
またこの関数は、シリアル化するオブジェクトについて、
すべての変数の名前を配列で返すことが前提となっています。
このメソッドが何も返さなかった場合は、NULL
がシリアル化され、E_NOTICE
が発生します。
注意:
__sleep() で、親クラスの private プロパティの名前を返すことはできません。 そうしようとすると
E_NOTICE
レベルのエラーとなります。 この場合は、かわりに Serializable インターフェイスを使います。
典型的な __sleep() の使用法は、 途中のデータをコミットしたり、 似たようなタスクのクリアを行うといったものです。 また、オブジェクトが非常に大きく、かつ、完全に保存する必要がない場合、 この関数が有用です。
逆に、unserialize() は、 特殊な名前 __wakeup() を有する 関数の存在を調べます。 もし存在する場合、この関数は、オブジェクトが有する可能性が あるあらゆるリソースを再構築することができます。
意図される __wakeup() の使用法は、 シリアル化の際に失われたデータベース接続を再度確立したり、 その他の再初期化を行うことです。
例1 sleep および wakeup
<?php
class Connection
{
protected $link;
private $dsn, $username, $password;
public function __construct($dsn, $username, $password)
{
$this->dsn = $dsn;
$this->username = $username;
$this->password = $password;
$this->connect();
}
private function connect()
{
$this->link = new PDO($this->dsn, $this->username, $this->password);
}
public function __sleep()
{
return array('dsn', 'username', 'password');
}
public function __wakeup()
{
$this->connect();
}
}?>
__toString() メソッドにより、
クラスが文字列に変換される際の動作を決めることができます。たとえば
echo $obj; としたときに何を表示させるかといったことです。
このメソッドは文字列を返さなければなりません。それ以外の場合は
E_RECOVERABLE_ERROR
レベルの致命的なエラーが発生します。
__toString() メソッド内から例外を投げることはできません。そうした場合、致命的なエラーが発生します。
例2 簡単な例
<?php
// 簡単なクラスを宣言
class TestClass
{
public $foo;
public function __construct($foo)
{
$this->foo = $foo;
}
public function __toString()
{
return $this->foo;
}
}
$class = new TestClass('Hello');
echo $class;
?>
上の例の出力は以下となります。
Hello
注意が必要なのは、PHP 5.2.0 より前では、
__toString() メソッドは
echo または print
と直接結合された場合のみコールされていたということです。
PHP 5.2.0 以降では、これはすべての文字列コンテキスト
(たとえば printf() における %s 修飾子)
でコールされます。しかし、その他の型のコンテキスト
(たとえば %d 修飾子) ではコールされません。
PHP 5.2.0 以降では、__toString()
メソッドを持っていないオブジェクトを文字列に変換しようとすると
E_RECOVERABLE_ERROR
が発生します。
__invoke() メソッドは、 スクリプトがオブジェクトを関数としてコールしようとした際にコールされます。
注意:
この機能は PHP 5.3.0 以降で使用可能です。
例3 __invoke() の使用
<?php
class CallableClass
{
public function __invoke($x)
{
var_dump($x);
}
}
$obj = new CallableClass;
$obj(5);
var_dump(is_callable($obj));
?>
上の例の出力は以下となります。
int(5) bool(true)
$properties
)この static メソッドは、 PHP 5.1.0 以降で var_export() によって エクスポートされたクラスのためにコールされます。
このメソッドの唯一のパラメータは、エクスポートされたプロパティを array('property' => value, ...) の形式で保持する配列です。
例4 __set_state() の使用法 (PHP 5.1.0 以降)
<?php
class A
{
public $var1;
public $var2;
public static function __set_state($an_array) // PHP 5.1.0 以降
{
$obj = new A;
$obj->var1 = $an_array['var1'];
$obj->var2 = $an_array['var2'];
return $obj;
}
}
$a = new A;
$a->var1 = 5;
$a->var2 = 'foo';
eval('$b = ' . var_export($a, true) . ';'); // $b = A::__set_state(array(
// 'var1' => 5,
// 'var2' => 'foo',
// ));
var_dump($b);
?>
上の例の出力は以下となります。
object(A)#2 (2) { ["var1"]=> int(5) ["var2"]=> string(3) "foo" }
注意: var_export() でオブジェクトをエクスポートする際に、そのオブジェクトのクラスが __set_state() を実装しているかどうかは確認しません。 一部の内部クラスを扱う際に、この影響が出てきます。 エクスポートしたオブジェクトをインポートする際に、 __set_state() を実装するクラスのものだけをインポートさせるようにするのは、プログラマーの責務となります。
このメソッドは、var_dump() がオブジェクトをダンプするときに、 プロパティの情報を取得するために呼ばれます。 もしオブジェクトにこのメソッドが定義されていなければ、 すべての public, protected, private プロパティを表示します。
この機能は PHP 5.6.0 で追加されました。
例5 __debugInfo() の使用法
<?php
class C {
private $prop;
public function __construct($val) {
$this->prop = $val;
}
public function __debugInfo() {
return [
'propSquared' => $this->prop ** 2,
];
}
}
var_dump(new C(42));
?>
上の例の出力は以下となります。
object(C)#1 (1) { ["propSquared"]=> int(1764) }