マジックメソッド
マジックメソッド一覧 ▲
説明コード記述
テストコード記述
関数 | 用途 |
---|---|
__construct | コンストラクタ |
__destruct | デストラクタ |
__call | アクセス不能メソッドをオブジェクトのコンテキストで実行したときに起動する |
__callStatic | アクセス不能メソッドを静的メソッドとして呼び出した場合に起動する |
__get | アクセス不能(protected または private)または存在しないプロパティからデータを読み込む際に使用される |
__set | アクセス不能(protected または private)または存在しないプロパティへデータを書き込む際に実行される |
__isset | isset() あるいは empty() をアクセス不能(protected または private)または存在しないプロパティに対して実行したときに起動する |
__unset | unset() をアクセス不能(protected または private)または存在しないプロパティに対して実行したときに起動する |
__sleep | オブジェクトをシリアライズ化した際に呼ばれる。 このメソッドでシリアライズしたい変数の変数名を配列として返すことで使用できる 親クラスの private プロパティの名前を返すことはできないのでその場合は __serialize を使用すること |
__wakeup | オブジェクトをアンシリアライズ化した際に呼ばれる。 シリアル化の際に失われたデータベース接続を再度確立したり、 その他の再初期化を行う |
__serialize | オブジェクトをシリアライズ化した際に呼ばれる。 __sleep と異なり、このメソッドでシリアライズしたいデータを"連想配列"の形で返すことで使用できる キー名も任意で設定できるため、変数名と一致させなくてもよくなる |
__unserialize | オブジェクトをアンシリアライズ化した際に呼ばれる。 __sleep & __wakeup と異なり、__serialize & __unserialize では任意の連想配列形式にできる分、アンシリアライズ時に渡されたデータから元の変数の状態を復元しなくてはいけない |
__toString | クラスが文字列に変換される際の動作を決めることができる |
__invoke | スクリプトがオブジェクトを関数としてコールしようとした際にコールされる |
__clone | オブジェクトのクローンが作成されるときに起動する 各プロパティに対して何も記載がなければシャローコピーとなる |
__construct ▲
__construct(mixed ...$values = ""): void
クラスのコンストラクタを宣言することができる
$values に任意の引数を設定することでクラスの生成時に外部から変数を渡すことができる
__destruct ▲
__destruct(): void
クラスのデストラクタを宣言することができる
特定のオブジェクトを参照するリファレンスがひとつもなくなったときにコールされる
ファイルのクローズ処理とか書くことが多いかも
__call ▲
public __call(string $name, array $arguments): mixed
アクセス不能メソッドをオブジェクトのコンテキストで実行したときに起動する
$name には実行しようとした関数名が入る
$arguments には実行しようとした関数に渡したパラメータが入る
__callStatic ▲
public static __callStatic(string $name, array $arguments): mixed
アクセス不能メソッドを静的メソッドとして呼び出した場合に起動する
$name には実行しようとした関数名が入る
$arguments には実行しようとした関数に渡したパラメータが入る
__get ▲
public __get(string $name): mixed
アクセス不能(protected または private)または存在しないプロパティからデータを読み込む際に使用される
$name には操作しようとしたプロパティの名前が入る
__set ▲
public __set(string $name, mixed $value): void
アクセス不能(protected または private)または存在しないプロパティへデータを書き込む際に実行される
$name には操作しようとしたプロパティの名前が入る
$value には $name に設定しようとした値が入る
__isset ▲
public __isset(string $name): bool
isset() あるいは empty() をアクセス不能(protected または private)または存在しないプロパティに対して実行したときに起動する
$name には操作しようとしたプロパティの名前が入る
__unset ▲
public __unset(string $name): void
unset() をアクセス不能(protected または private)または存在しないプロパティに対して実行したときに起動する
$name には操作しようとしたプロパティの名前が入る
__sleep ▲
public __sleep(): array
オブジェクトをシリアライズ化した際に呼ばれる。
親クラスの private プロパティの名前を返すことはできないのでその場合は __serialize を使用すること
__sleep も __serialize もない状態で serialize() を呼んだ場合は見境なく全てシリアライズ化しようとするので、シリアライズ化不要なデータがある場合はどちらかを使用する
class Sample
{
protected $connection; // コネクションなどは使用するタイミングで繋ぐものなのでシリアライズ化はいらない
private $username, $password; // この2つをシリアライズ化しておけばよい
public function __sleep()
{
return array('username', 'password');
}
}
上記のようにクラス内のシリアライズ化したい変数の変数名を __sleep メソッド内で返すようにする
__wakeup ▲
public __wakeup(): void
オブジェクトをアンシリアライズ化した際に呼ばれる。
下記のようにコネクションを繋ぎなおしたい場合や、変数展開した上で初期化処理を通したい場合などに使用する
class Sample
{
protected $connection; // アンシリアライズ時に復元したい
private $username, $password; // シリアライズ時に残っている情報
public function __sleep()
{
return array('username', 'password');
}
public function __wakeup()
{
// username と password は変数展開されるが、connection は新たに繋ぎなおす必要がある
$this->connect();
}
private function connect()
{
$this->connection = new Connection($this->username, $this->password);
}
}
__serialize ▲
public __serialize(): array
オブジェクトをシリアライズ化した際に呼ばれる
__sleep とは異なり、連想配列形式でシリアライズ時のデータを設定できる
__sleep と __serialize の両方が定義されていた場合は __serialize のほうが優先される
PHP 7.4.0 以降から使用可能
__unserialize ▲
public __unserialize(array $data): void
オブジェクトをアンシリアライズ化した際に呼ばれる
__wakeup と __unserialize の両方が定義されていた場合は __unserialize のほうが優先される
__wakeup では unserialize() に渡されたデータの中で同じ変数名のものがあれば自動で展開されていたが、__unserialize の場合は全て自分で展開しなければいけない
PHP 7.4.0 以降から使用可能
__toString ▲
public __toString(): string
クラスが文字列に変換される際の動作を決めることができる
PHP 8.0.0 以降では __toString を含む全てのクラスは暗黙のうちに Stringable インターフェースを実装するようになったが、明示的に実装しておくほうがよいので忘れずにつけておくこと
__invoke ▲
__invoke( ...$values): mixed
スクリプトがオブジェクトを関数としてコールしようとした際にコールされる
公式ドキュメントにあったソートの使用例が参考になったので貼っておく
class Sort
{
private $key;
/**
* コンストラクタ
*
* @param string $key ソートに使用するキー名
*/
public function __construct(string $key)
{
$this->key = $key;
}
/**
* ソート処理で使用するメソッド
*
* @param array $a 比較対象a
* @param array $b 比較対象b
* @return integer 結果
*/
public function __invoke(array $a, array $b): int
{
return $a[$this->key] <=> $b[$this->key];
}
}
// データ例
$customers = [
['id' => 1, 'first_name' => 'John', 'last_name' => 'Do'],
['id' => 3, 'first_name' => 'Alice', 'last_name' => 'Gustav'],
['id' => 2, 'first_name' => 'Bob', 'last_name' => 'Filipe']
];
//================================================================================//
// 本来 usort の第2引数は『callback(mixed $a, mixed $b): int 』を渡さないといけないが、
// Sort クラスの __invoke に上記の条件に沿った関数を設定することで実現している
//================================================================================//
// $customers を 'first_name' でソートします
usort($customers, new Sort('first_name'));
print_r($customers);
// $customers を 'last_name' でソートします
usort($customers, new Sort('last_name'));
print_r($customers);
__clone ▲
__clone(): void
オブジェクトのクローンが作成されるときに起動する
各プロパティに対して何も記載がなければシャローコピーとなる
class SubObject
{
public $value;
}
class MainObject
{
public $sub1;
public $sub2;
public function __construct()
{
$this->sub1 = new SubObject();
$this->sub2 = new SubObject();
}
public function __clone()
{
$this->sub1 = clone $this->sub1;
}
}
$main = new MainObject();
$main->sub1->value = 1;
$main->sub2->value = 2;
// クローンを作成する(ディープコピーしたい)
$clone = clone $main;
// メイン側だけ書き換える
$main->sub1->value = 3;
$main->sub2->value = 4;
// MainObject クラスの __clone メソッドでディープコピーしていない sub2 はメイン側と一緒に書き変わってしまう
echo $clone->sub1->value; // 1 OK
echo $clone->sub2->value; // 4 NG
目次