PHP展开数组单例构造函数

时间:2011-02-04 17:03:14

标签: php singleton

我尝试实现一个能够将参数传递给教师的单例模式。对于单例模式,我想创建一个基类。这个问题的主要问题是并非所有派生类都具有相同数量的参数。对于单身基类,到目前为止我有这个:

abstract class Singleton
{
    /**
     * Function: __construct
     * Description: the function which creates the object.
     */
    protected function __construct()
    {

    }
    private final function __clone()
    {
    }
    public static function getInstance()
    {
        $args = func_get_args();
        static $instance = null;

        return $instance = $instance ?  : new static();
    }
}    

到目前为止,这是有效的,但是我不能用这个将参数传递给构造函数。当然我可以直接将$ args数组传递给构造函数,但我不想在派生类的每个构造函数中展开数组,我希望能够将参数作为普通参数传递。

我已经尝试了几件事:我尝试使用call_user_func_array,但我无法弄清楚如何用这个函数构造一个对象(如果它可能的话),我也尝试使用ReflectionClass。 ReflectionClass的问题是这个类无法访问构造函数,因为构造函数受到保护。

所有人对我有什么想法如何解决这个问题?

PS。对不起,如果我表现得很困难,但我只是想找到最好的解决方案(并了解解决方案)。

2 个答案:

答案 0 :(得分:2)

首先,您最好使用静态成员变量。由于您无法动态调用new,因此您无法使用init函数。

我将如何做到:

abstract class Singleton
{
    protected static $instances = array();
    /**
     * Function: __construct
     * Description: the function which creates the object.
     */
    private function __construct()
    {
    }
    private final function __clone()
    {
    }

    protected abstract function _init();

    public static function getInstance()
    {
        $args = func_get_args();
        $class = strtolower(get_called_class());
        if (!isset(self::$instances[$class])) {
            self::$instances[$class] = new $class();
            call_user_func_array(
                array(
                    self::$instances[$class],
                    '_init'
                ),
                $args
            );
        }
        return self::$instances[$class];
    }
}

因此,您的扩展类将使用_init而不是__construct

class foo extends Singleton {
    protected function _init($foo) {
        $this->foo = $foo;
    }
}

请注意,Singleton::__construct现在是私有的,以防止被误用。

所有这些都不是因为singletonsevilshouldavoided。所以如果你必须使用它们,你可以。但找到一个更好的方法,因为他们真的那么糟糕......

答案 1 :(得分:1)

如果您的意思是在实例中需要一些默认设置,则可以在子设备中设置私有设置数组:

class Simpleton extends Singleton
{
  private $settings;

  protected function __construct()
  {
    $this->settings = array(
      //default settings here
    );
  }
}

不要尝试将参数合并到单例中。如果你需要一个参数化的构造函数,不要打扰单例。

单身人士应该有默认值,然后是访问者/变异者,用于调整任何可以调整的设置。