PHP5.3以降から遅延静的束縛と言う機能が追加され調べてみた。
親クラスの静的メソッドを小クラスでオーバーライドする機能。
はじめに下記の事を理解すれば分かり易いかも・・・
非転送コール |
C::foo() や$c->foo() といったクラス名(もしくはオブジェクト)を明示した呼び出し |
転送コール |
self:: parent:: static:: もしくはクラス階層の中での forward_static_call() での呼び出し |
遅延静的束縛 | 非転送コール時に、明示されたクラス名(もしくはオブジェクトのクラス名)を保持する機能 |
selfの場合
//selfの場合
<?php
class ParentClass {
public function sayHello() {
self::hello();
}
public static function hello() {
echo __CLASS__. ' hello!';
}
}
class ChildClass extends ParentClass {
public static function hello() {
echo __CLASS__. ' hello!!';
}
}
$hello = new ChildClass();
$hello->sayHello(); //ParentClass hello!
?>
小クラスでhello
メソッドをオーバーライドさせて
sayHello
メソッドを継承させればself::はChildClass
で
解決すると思いきや、実際はParentClass
で解決される!
何故か↓
PHPマニュアルより
`self::`あるいは`CLASS`による現在のクラスへの
静的参照は、そのメソッドが属するクラス
(つまり、そのメソッドが定義されているクラス) に解決されます。
らしい。
と言う事はself::hello()
はParentClass::hello()
となる。
(これじゃぁダメぇダメぇ。。。)
staticの場合
//staticの場合
<?php
class ParentClass {
public function sayHello() {
static::hello();
}
public static function hello() {
echo __CLASS__. ' hello!';
}
}
class ChildClass extends ParentClass {
public static function hello() {
echo __CLASS__. ' hello!!';
}
}
$hello = new ChildClass();
$hello->sayHello(); //ChildClass hello!
?>
では5.3で用意された遅延静的束縛のstaticで上記のようにすると
思うような結果得られる。
PHPマニュアルより
遅延静的束縛は直近の “非転送コール” のクラス名を保存します。
今回のサンプルコードはいたって単純で行数が増えてくると???になりそうだ。。。
感じとしてはstaticは非転送コール時に、明示されたクラス名(もしくはオブジェクトのクラス名)を保持する機能と言う事とstaticは、静的な変数の定義 や 静的遅延束縛 にも使える。
先ずはここを頭に置いておかないと。。。