マジックメソッドは、 ある動作がオブジェクトに対して行われた場合に、 PHP のデフォルトの動作を上書きする特別なメソッドです。
__で始まる全てのメソッドは、 PHP によって予約されています。 よって、PHP の動作を上書きするのでなければ、 このようなメソッド名を使うことは推奨されません。
__construct(), __destruct(), __clone() を除く全てのマジックメソッドは、 public として宣言しなければいけません。 そうしないと、 E_WARNING レベルの警告が発生します。
__callStatic以外、静的呼び出しには対応しない。
マジックメソッドの定義で型宣言が使われている場合、 それらは、このマニュアルで説明しているシグネチャと同じでなければいけません。
それぞれのメソッドで戻り値は決まっている。
プロパティのオーバーロードはオブジェクトのコンテキストでのみ動作します。 これらのマジックメソッドは、static メソッドとしては呼び出されません。 したがって、これらのメソッドを static メソッドとして宣言してはいけません。 マジックメソッドを static メソッドとして宣言すると警告が発生します。
主なマジックメソッド
メソッド | 呼び出しのタイミング | 戻り値 |
---|---|---|
__get | 未定義のプロパティを取得しようとしたとき | mixed |
__set | 未定義のプロパティを設定しようとしたとき | void |
__isset | 未定義のプロパティをisset関数で処理しようとしたとき | bool |
__unset | 未定義のプロパティをunset関数で処理しようとしたとき | void |
__call | 未定義のインスタンスメソッドをコールしたとき | mixed |
__callStatic | 未定義の静的メソッドをコールしたとき | mixed |
__toString | print命令などでオブジェクトの文字列表現を要求されたとき | string |
__invoke | オブジェクトが関数の形式で呼び出されたとき | mixed |
__clone | clone命令でオブジェクトを複製したとき | void |
__debuginfo | var_dump命令でオブジェクトをダンプしようとしたとき | array |
__construct | 新たにオブジェクトが 生成される度にこのメソッドをコールします。 子クラスでオーバライドしても、 シグネチャの互換性に関するルール(注1)は適用されません。 | void |
__destruct | 特定のオブジェクトを参照するリファレンスがひとつもなくなったときにコールされます。 あるいは、スクリプトの終了時にも順不同でコールされます。 | void |
メソッドをオーバーライドするときは、 子クラスのシグネチャが親クラスのそれと互換性がなければいけません。 互換性が壊れた場合、致命的なエラーが発生します。 PHP 8.0.0 より前のバージョンでは、 互換性が壊れた場合に、E_WARNING レベルの警告が発生していました。
但し、コンストラクタ と private メソッドについては、 この規則の例外で、 オーバライドしたシグネチャにミスマッチがあっても致命的なエラーにはなりません。
__set でメソッドを追加する
bindToメソッド
public Closure::bindTo(?object $newThis, object|string|null $newScope = “static”): ?Closure
class Person {
public string $firstName;
public string $lastName;
private array $methods = [];
public function __set(string $name, Closure $method) : void {
$this->methods[$name] = $method->bindTo($this, self::class);
}
public function __call(string $name, array $args) : mixed {
if (!array_key_exists($name, $this->methods)) {
throw new Exception("${name} method is not existed.");
}
return $this->methods[$name](...$args);
}
}
$p = new Person();
$p->lastName = '東京';
$p->firstName = '太郎';
$p->bye = function(): void { //無名関数を登録する(Closure)
print "{$this->lastName}{$this->firstName}さん";
};
$p->bye();
public __call(string $name, array $arguments): mixed
未定義のインスタンスメソッドをコールしたとき。
引数 $arguments は配列で、メソッド $name に渡そうとしたパラメータが格納されます。
__clone(): void
オブジェクトのクローンが作成される際、PHP は、そのオブジェクトのプロパティを 全てシャローコピーします。他の変数へのリファレンスを保持する全てのプロパティは、 リファレンスのままとなります。ディープコピーしたい場合は、foreach命令で複製を生成する。
public function __clone():void {
foreach($this->list as &$value) {
$value = clone $value;
}
}