PHP5.3で追加された遅延静的束縛(Late Static Bindings)について調べ直した
前にまとめたPHP5系で追加された機能を振り返る記事の続き。今回は、よく理解していなかった遅延静的束縛について調べ直した。
転送コールと非転送コールとは
遅延静的束縛を理解するために、先にこの2つについてまとめる。
▼ 転送コールとは
self / parent / static
キーワードによる静的なコール- クラス階層の中での
forward_static_call()
によるコール
▼ 非転送コールとは
Hoge::foo()
、$hoge->foo()
のようなクラス名やオブジェクトを明示したコール
遅延静的束縛とは
遅延静的束縛とは、 直近の非転送コールのクラス名 を保存する機能のことである。この機能はstatic
キーワードを用いる。(ちなみにstatic
キーワードは、遅延静的束縛以外にも、静的なメソッドやプロパティや変数の定義にも用いるので、意味がごちゃごちゃにならないように注意。)
例えば、以下のようなコードがあるとする。
<?php class A { protected static $message = 'salmon'; public static function getSelfMessage() { return self::$message; } public static function getStaticMessage() { return static::$message; } } class B extends A { protected static $message = 'nyaaaan'; } var_dump([ A::getSelfMessage(), // salmon B::getSelfMessage(), // salmon A::getStaticMessage(), // salmon B::getStaticMessage(), // nyaaaan ]);
self
キーワードの場合、そのメソッドが属するクラスが参照されるため、A::getSelfMessage()
、B::getSelfMessage()
のどちらも、そのメソッドが属するAクラスに存在する$message = 'salmon'
が出力される。
それに対し、static
キーワードの場合、遅延静的束縛で直近の非転送コールのクラスを参照するため、B::getStaticMessage()
はBクラスに存在する$message = 'nyaaaan'
が出力される。
また、以下のようなコードがあるとする。
<?php class C { protected static $message = 'board game'; public static function getMessage() { return C::getStaticMessage(); } public static function getStaticMessage() { return static::$message; } } class D extends C { protected static $message = 'sushi'; } var_dump([ C::getMessage(), // board game D::getMessage(), // board game ]);
static
キーワードは 直近の 非転送コールのクラスを参照するため、D::getMessage()
はCクラスに存在する$message = 'board game'
を出力する。
所感
Laravelなどのフレームワークやライブラリで遅延静的束縛を用いた処理はよく見かけるので、きちんと理解しておけば、各フレームワークやライブラリの挙動を追いやすくなって良さそうだと思った。