Late Static Binding

I have a little problem. Here he is:

  • This is my abstract abstract class:

    abstract class Singleton { protected static $_instance = NULL; /** * Prevent direct object creation */ final private function __construct() { $this->actionBeforeInstantiate(); } /** * Prevent object cloning */ final private function __clone() { } /** * Returns new or existing Singleton instance * @return Singleton */ final public static function getInstance(){ if(null !== static::$_instance){ return static::$_instance; } static::$_instance = new static(); return static::$_instance; } abstract protected function actionBeforeInstantiate(); } 
  • After that, I create an abstract registry class:

     abstract class BaseRegistry extends Singleton { //... } 
  • Now it's time for the session registry.

     class BaseSessionRegistry extends BaseRegistry { //... protected function actionBeforeInstantiate() { session_start(); } } 
  • Last step:

     class AppBaseSessionRegistryTwo extends BaseSessionRegistry { //... } class AppBaseSessionRegistry extends BaseSessionRegistry { //... } 
  • Testing

     $registry = AppBaseSessionRegistry::getInstance(); $registry2 =AppBaseSessionRegistryTwo::getInstance(); echo get_class($registry) . '|' . get_class($registry2) . '<br>'; 

Output:

 AppBaseSessionRegistry|AppBaseSessionRegistry 

My expectations were:

 AppBaseSessionRegistry|AppBaseSessionRegistryTwo 

Why did I get such a result? And how can I redo my code to get the result that I expected?

UPDATE: I use this as part of my framework. And users will extend my BaseSessionRegistry class and add them. I want to solve this problem within my framework classes

+7
source share
3 answers

You need to do this:

 class AppBaseSessionRegistryTwo extends BaseSessionRegistry { protected static $_instance = NULL; // ... } class AppBaseSessionRegistry extends BaseSessionRegistry { protected static $_instance = NULL; //... } 

If you do not declare the static property separately, they will use the same static property of their parent.

Update: If you do not want the children to declare a static property, you can declare the static property as an array of the parent element.

 abstract class Singleton { protected static $_instances = array(); // ... /** * Returns new or existing Singleton instance * @return Singleton */ final public static function getInstance(){ $class_name = get_called_class(); if(isset(self::$_instances[$class_name])){ return self::$_instances[$class_name]; } return self::$_instances[$class_name] = new static(); } abstract protected function actionBeforeInstantiate(); } 
+4
source

Your first line:

 $registry = AppBaseSessionRegistry::getInstance(); 

populates protected static $_instance instance of AppBaseSessionRegistry . The next line is $registry2 =AppBaseSessionRegistryTwo::getInstance(); protected static $ _instance already matters, and this instance will be returned.

Generally speaking, singleton and statics are evil. Their combination is terrible. Get involved in good OO programming and avoid singletones and static.

+1
source
  $registry = AppBaseSessionRegistry::getInstance(); 

The above statement sets $ _instance with an object of class AppBaseSessionRegistry
since in the getInstance method we check to see if it was previously set, and then return this value for your second statement

 $registry2 =AppBaseSessionRegistryTwo::getInstance(); 

getInstance will return an object of class AppBaseSessionRegistry ie $ registry1 and registry 2, referring to the same object

+1
source

All Articles