今回はPHPのマジックメソッドの使い方について説明します。
PHPのクラスにおいて__get()
や__set()
等のように、__で始まる関数はマジックメソッドと呼ばれる特殊な関数です。
それぞれ特定の条件下において実行されるようになっているため、普段は中々使う機会が無いかもしれませんが、PHPのフレームワークやライブラリでは使われていることがあります。
そのため、フレームワークやライブラリのコードを読む際には、マジックメソッドが使われていることに気づかないと、どうやって処理が実行されているのか、把握できなくなる恐れがあります。
ですので、良く使用されるマジックメソッドを抑えておくと、フレームワークやライブラリのコードリーディングが捗るかと思います。
また、マジックメソッドの効果的な使い方がわかるようになると、より柔軟なプログラムを書くことができるようになるというメリットもあります。
但し、マジックメソッドを乱用すると、可読性を損ねてしまうことがあるので、十分に気をつけましょう。
要約
- マジックメソッドを覚えておくと、フレームワークやライブラリを読むのに役立つ
- 適切に使えれば、柔軟なコードを書くことができる
- 乱用すると可読性を損ねる恐れがある
解説
それではPHPの各マジックメソッドについて説明します。
ただ、マジックメソッドの全てを解説できていないので、その他のマジックメソッドについては、下記のリンクを参照下さい。
__get()
クラスに存在しないプロパティを参照しようとした時に呼び出されます。
class MagicMethod
{
public function __get($name)
{
return 'property does not exist';
}
}
$magic = new MagicMethod;
$magic->bar; // "property does not exist"
__set()
クラスに存在しないプロパティに値を代入しようとした時に呼び出されます。
class MagicMethod
{
public function __set($name, $value)
{
// $nameの変数を動的に生成して、$valueをセット
$this->$name = $value;
}
}
$magic = new MagicMethod;
$magic->foobar = 1234;
$magic->foobar // 1234
__call()
アクセス不能なメソッドを実行しようとしたタイミングで呼び出されます。
アクセス不能というのは、メソッドが存在しない、またはprivateやprotectedのため、外部から実行できない等です。
class MagicMethod
{
public function __call($name, $arguments)
{
return 'method does not exist or can not call';
}
private function canNotCall()
{
return true;
}
}
$magic = new MagicMethod;
$magic->method() // "method does not exist or can not call"
$magic->canNotCall() // "method does not exist or can not call"
__callStatic()
アクセス不能なメソッドを静的に実行しようとしたタイミングで呼び出されます。
class MagicMethod
{
public static function __callStatic($name, $arguments)
{
return 'static method does not exist';
}
}
MagicMethod::staticMethod() // "static method does not exist"
__invoke()
オブジェクトを関数として実行しようとしたときに呼び出されます。
class MagicMethod
{
public function __invoke()
{
return true;
}
}
$magic = new MagicMethod;
$magic() // true
以上、幾つかのマジックメソッドの使用方法を記載しました。
マジックメソッドが実際どのように使用されているかというと、例えばPHPフレームワークのLaravelでは、ファサードという機能の実装に__callStatic()が使われています。
ファサードについては別の記事で解説していますので、そちらも参照してみて下さい。

マジックメソッドは慣れない間は使いどころが無いように感じられるかもしれませんが、変数や処理を動的にクラスに追加することができたりと、メリットも大きいので色々なコードを参考に試してみてはいかがでしょうか。