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は、静的な変数の定義 や 静的遅延束縛 にも使える。
先ずはここを頭に置いておかないと。。。