Я хотел бы начать с показа теста:
class A { public static $instance=null; public function __construct(){ self::$instance=$this; } public function className(){ return get_class(self::$instance); } } class B extends A { public function className(){ return get_class(self::$instance); } } // test code $b=new B(); echo $b->className; // B $a=new A(); echo $a->className; // A echo $b->className; // A <- error: not B any more!
Заметки
Проблемы заключаются в том, что self::$instance
одинаково для всех экземпляров. Как отделить self::$instance
для каждого класса?
Edit: У меня была эта идея:
$GLOBALS['store']=array(); class A { public static $instance=null; public function __construct(){ $GLOBALS['store'][__CLASS__]=$this; } }
Вы можете сохранить экземпляр для каждого имени класса:
class A { public static function getInstance(){ // Maybe use this function to implement the singleton pattern ... return self::$instance[get_called_class()]; } public function className(){ return get_class(self::getInstance()); } }
Вы не можете сделать это чистым способом. Это один из недостатков мэра по свойствам stati: вы не можете их переопределить.
Но вы хотите, чтобы решение было таким … вот что беспокоит: используйте __calllStatic
<?php class A { public static function __callstatic($name,$args) { if($name="getClass"){ return 'A'; } } } class B extends A{ public static function __callstatic($name,$args) { if($name="getClass"){ return 'B'; } } } echo A::getClass(); echo B::getClass(); ?>
вывод этого – «AB»;
Вы можете добавить public static $instance=null;
декларация в классе B.
class A { public static $instance=null; public function __construct(){ self::$instance=$this; } public function className(){ return get_class(self::$instance); } } class B extends A { public static $instance=null; public function className(){ return get_class(self::$instance); } } // test code $b=new B(); echo $b->className(); // B $a=new A(); echo $a->className(); // A echo $b->className(); // Now returns B, as desired.