Расширяющий класс PHP заставляет детей наследовать одно и то же статическое свойство - PullRequest
2 голосов
/ 17 декабря 2010

Я хотел бы начать с показа контрольного примера:

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!

Примечания

  • Я использую заводские + одиночные шаблоны выше,Ну, в некоторой степени.
  • Мне не нужны какие-либо спецификации на "правильную реализацию шаблонов".Мне нужно решение проблем, а не нарушения KISS;).
  • Критики могут сказать, что А должен быть интерфейсом.В идеале, так и должно быть, но это просто простой класс, извините.

Проблема заключается в том, что self::$instance одинаково для всех экземпляров.Как мне выделить self::$instance для каждого класса?

Редактировать: У меня была такая идея:

$GLOBALS['store']=array();
class A {
    public static $instance=null;
    public function __construct(){
        $GLOBALS['store'][__CLASS__]=$this;
    }
}

Ответы [ 3 ]

3 голосов
/ 17 декабря 2010

Вы можете сохранить экземпляр для имени класса:

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());
    }   
}
1 голос
/ 18 декабря 2010

Вы можете добавить объявление 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.
1 голос
/ 17 декабря 2010

Вы не можете сделать это чистым способом.Это один из недостатков мэра в отношении свойств 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";

...