使用PHP 5.4构建Singleton特征

edo*_*ian 22 php traits

我们最近讨论过是否有可能构建一个trait Singleton PHP Traits,我们在其中使用了一个可能的实现但遇到了构建问题的问题.

这是一项学术活动.我知道这一点Singletons have very little - if not to say no - use in PHP,one should 'just create one'但仅仅是为了探索特征的可能性:

<?php
trait Singleton
{
    protected static $instance;
    final public static function getInstance()
    {
        return isset(static::$instance)
            ? static::$instance
            : static::$instance = new static;
    }
    final private function __construct() {
        static::init();
    }
    protected function init() {}
    final private function __wakeup() {}
    final private function __clone() {}    
}

class A  {
    use Singleton;
    public function __construct() {
        echo "Doesn't work out!";
    }
}

$a = new A(); // Works fine
Run Code Online (Sandbox Code Playgroud)

重现:http://codepad.viper-7.com/NmP0nZ

问题是:可以在PHP中创建Singleton Trait吗?

edo*_*ian 29

我们找到的快速解决方案(谢谢聊天!):

如果特征和类都定义了相同的方法,则使用类的方法

所以Singleton特性只有在使用它的类没有定义a时才有效 __construct()

特征:

<?php
trait Singleton
{
    protected static $instance;
    final public static function getInstance()
    {
        return isset(static::$instance)
            ? static::$instance
            : static::$instance = new static;
    }
    final private function __construct() {
        $this->init();
    }
    protected function init() {}
    final private function __wakeup() {}
    final private function __clone() {}    
}
Run Code Online (Sandbox Code Playgroud)

消费类的示例:

<?php    
class A  {
    use Singleton;

    protected function init() {
        $this->foo = 1;
        echo "Hi!\n";
    }
}

var_dump(A::getInstance());

new A();
Run Code Online (Sandbox Code Playgroud)

var_dump现在产生预期的输出:

Hi!
object(A)#1 (1) {
  ["foo"]=>
  int(1)
}
Run Code Online (Sandbox Code Playgroud)

而新的失败:

Fatal error: Call to private A::__construct() from invalid context in ...
Run Code Online (Sandbox Code Playgroud)

Demo