Late static binding

I've got a little problem. Here it is:

  1. This is my singleton 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();
    
    }
    
  2. After that I create an abstract registry class:

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

    class BaseSessionRegistry extends BaseRegistry
    {
    
    //...
    
    protected function actionBeforeInstantiate()
    {
        session_start();
    }
    
    }
    
  4. The final step:

    class AppBaseSessionRegistryTwo extends BaseSessionRegistry { //... }
    
    class AppBaseSessionRegistry extends BaseSessionRegistry { //... }
    
  5. 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 result? And how can I remake my code to obtain result that I expected?

UPDATE: i use this in my framework. And users will extend my BaseSessionRegistry class and will add their stuff. I want to solve this inside my framework classes

Answers


You need to do this:

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

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

If you don't declare static property separately, they will share the same static property of their parent.

Update: If you don't want the children declare the static property, then you could declare the static property as an array of the parent.

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();

}

Need Your Help

Do I need a server written in node.js instead of a regular nginx/Apache?

node.js nginx

I'd like to use node.js to add basic functionality to a static site:

Implementing a Finite State machine in C

c project finite-state-machine

I have been writing a code that either accepts or rejects a string of input symbols as part of a specified language. And I have written code for the first language but it doesn't accept the right t...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.