パターン
finalキーワード
クラスとオブジェクト
PHP Manual

## マジックメソッド

以下の関数名 __construct, __destruct, __call, __callStatic, __get, __set, __isset, __unset, __sleep, __wakeup, __toString, __invoke, __set_state および __clone は、PHP クラスにおける特殊関数の名前です。 これらの関数に関連する特別な機能を使用する場合を除き、 クラス内にこれらの名前を有する関数を作成してはいけません。

警告

PHP は、__ で始まる関数名を特殊関数として予約しています。 文書化された特殊な機能を必要とする場合を除き、 __ で始まる関数名を使用しないことが推奨されます。

### __sleep と __wakeup

serialize() は、クラスに特殊な名前 __sleep の関数があるかどうかを調べます。 もしあれば、シリアル化の前にその関数を実行します。 この関数で、オブジェクトをクリアすることができます。 またこの関数は、シリアル化するオブジェクトについて、 すべての変数の名前を配列で返すことが前提となっています。 このメソッドが何も返さなかった場合は、`NULL` がシリアル化され、`E_NOTICE` が発生します。

> 注意: __sleep で、親クラスの private プロパティの名前を返すことはできません。 そうしようとすると `E_NOTICE` レベルのエラーとなります。 この場合は、かわりに Serializable インターフェイスを使います。

典型的な __sleep の使用法は、 途中のデータをコミットしたり、 似たようなタスクのクリアを行うといったものです。 また、オブジェクトが非常に大きく、かつ、完全に保存する必要がない場合、 この関数が有用です。

逆に、unserialize() は、 特殊な名前 __wakeup を有する 関数の存在を調べます。 もし存在する場合、この関数は、オブジェクトが有する可能性が あるあらゆるリソースを再構築することができます。

意図される __wakeup の使用法は、 シリアル化の際に失われたデータベース接続を再度確立したり、 その他の再初期化を行うことです。

例1 Sleep および wakeup

`<?php
class Connection {
protected $link;
private $server, $username, $password, $db;
public function __construct($server, $username, $password, $db)
{
$this->server = $server;
$this->username = $username;
$this->password = $password;
$this->db = $db;
$this->connect();
}
private function connect()
{
$this->link = mysql_connect($this->server, $this->username, $this->password);
mysql_select_db($this->db, $this->link);
}
public function __sleep()
{
return array('server', 'username', 'password', 'db');
}
public function __wakeup()
{
$this->connect();
}
}
?>`

### __toString

__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

__invoke メソッドは、 スクリプトがオブジェクトを関数としてコールしようとした際にコールされます。

> 注意: この機能は PHP 5.3.0 以降で使用可能です。

例3 __invoke の使用

`<?php
class CallableClass {
function __invoke($x) {
var_dump($x);
}
}
$obj = new CallableClass;
$obj(5);
var_dump(is_callable($obj));
?>`

上の例の出力は以下となります。

    int(5)
    bool(true)

### __set_state

この 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"
    }

パターン
finalキーワード
クラスとオブジェクト
PHP Manual