__CLASS__ 定数の遅延静的束縛版といったところでしょうか。
<?php class A { public static function whose() { return get_called_class(); } } class B extends A { public static function whose() { return parent::whose(); } } class C extends A { public static function whose() { return A::whose(); } } echo 'A: ', A::whose(), PHP_EOL; echo 'B: ', B::whose(), PHP_EOL; echo 'C: ', C::whose(), PHP_EOL;
A: A B: B C: A
ActiveRecord のようにクラスメソッドがバカスカ生えるクラスに使えるかもですね。でもここでは継承される事を想定したシングルトンの例を上げます。そんなのありか!
<?php class Hoge { private static $instances = array(); protected function __construct() { if (array_key_exists(get_called_class(), self::$instances)) { throw new RuntimeException('もう作っちゃらめ!'); } } final public static function getInstance() { $callee = get_called_class(); if (!array_key_exists($callee, self::$instances)) { self::$instances[$callee] = new static(); } return self::$instances[$callee]; } public function __clone() { throw new RuntimeException('クローン作っちゃらめ!'); } public function __toString() { return get_class($this) . '(' . spl_object_hash($this) . ')'; } } class Fuga extends Hoge { } class Piyo extends Fuga { } echo Hoge::getInstance(), PHP_EOL; echo Fuga::getInstance(), PHP_EOL; echo Piyo::getInstance(), PHP_EOL; echo Hoge::getInstance(), PHP_EOL; echo Fuga::getInstance(), PHP_EOL; echo Piyo::getInstance(), PHP_EOL;
Hoge(ea3b5927dbfffe7c0456ff51c413a384) Fuga(0e67c95a7d082c779dc82db7e8554d9c) Piyo(3b3af9abb7c1ee816230684be1ec11dc) Hoge(ea3b5927dbfffe7c0456ff51c413a384) Fuga(0e67c95a7d082c779dc82db7e8554d9c) Piyo(3b3af9abb7c1ee816230684be1ec11dc)