【问题标题】:Why does PHP create a new instance of a singleton each time the script calling Foo::getInstance() is run?为什么每次运行调用 Foo::getInstance() 的脚本时 PHP 都会创建一个新的单例实例?
【发布时间】:2013-07-07 19:07:45
【问题描述】:

我一直怀疑 PHP 单例不是真正的单例,所以我做了一个测试。我创建了以下类:

class MySingleton {


    private static $instance;


    private function __construct()
    {
        error_log("I am a new instance of MySingleton. I was instantiated at " . time());
    }


    private function __clone(){}


    public static function getInstance()
    {
        if(!is_object(self::$instance)) {
            self::$instance = new MySingleton();
        }
        return self::$instance;
    }

}

接下来我创建了一个名为 test.php 的文件:

require('MySingleton.php');

$foo = MySingleton::getInstance();
$bar = MySingleton::getInstance();
$baz = MySingleton::getInstance();

当我在本地主机上运行 test.php 脚本时,我在 Apache 错误日志中得到一个条目,这使它看起来像它应该做的那样。但是,每次我在浏览器中刷新页面时,我都会在错误日志中看到另一个条目,这意味着 PHP 正在实例化一个新对象。

我可以做些不同的事情来使此类返回对象的持久单实例吗? (即单身人士应该做什么)。

请不要对你认为单身不好的所有原因做出回应。我已经熟悉这些谈话要点。

提前致谢!

【问题讨论】:

    标签: php singleton


    【解决方案1】:

    在 PHP 中,单例对象一直存在到脚本存在为止。这里发生的情况是,一旦您的请求完成,脚本就会终止。对于第二个请求,它会创建一个新的脚本实例,从而创建一个新的 MySingleton 对象。

    【讨论】:

      【解决方案2】:

      PHP 是无状态的。在每次请求时,应用程序都会被构建和拆除。在这种情况下,您的单例在应用程序的整个过程中只被实例化一次——即每个请求一次。

      相比之下,Java 之类的东西有一个服务器,例如 Tomcat 或 Jetty,它将对象加载到内存中。在这种情况下,您的单例将在多个请求中存活...直到服务器重新启动。

      【讨论】:

      • 有趣(但令人失望)。既然如此,我想为了在 PHP 中有一个真正的单例,我必须序列化实例并将其存储在 APC 用户缓存中。然后 getInstance() 方法将检查缓存而不是检查 self::$instance。不过,这似乎很糟糕。
      最近更新 更多