实现PHP单例:静态类属性还是静态方法变量? - php

因此,我总是像这样实现单例:

class Singleton {
    private static $_instance = null;
    public static function getInstance() {
        if (self::$_instance === null) self::$_instance = new Singleton();
        return self::$_instance;
    }
    private function __construct() { }
}

但是,最近让我感到震惊的是,我也可以使用基于成员的静态变量来实现它:

class Singleton {
    public static function getInstance() {
        //oops - can't assign expression here!
        static $instance = null; // = new Singleton();
        if ($instance === null) $instance = new Singleton();
        return $instance;
    }
    private function __construct() { }
}

对我来说,这比较干净,因为它不会使类混乱,并且我不必进行任何显式的存在性检查,但是由于我从未在其他地方看到此实现,所以我想知道:

使用第二种实现而不是第一种实现有什么问题吗?

参考方案

您可能会稍加修改就表示它的意思(否则会出现语法错误):

<?php
class Singleton {
    public static function getInstance() {
        static $instance;
        if ($instance === null)
            $instance = new Singleton();
        xdebug_debug_zval('instance');
        return $instance;
    }
    private function __construct() { }
}
$a = Singleton::getInstance();
xdebug_debug_zval('a');
$b = Singleton::getInstance();
xdebug_debug_zval('b');

这给出:

实例:(refcount = 2,is_ref = 1),
对象(单身)[1]

a:(refcount = 1,is_ref = 0),
对象(单身)[1]

实例:(refcount = 2,is_ref = 1),
对象(单身)[1]

b:(refcount = 1,is_ref = 0),
对象(单身)[1]

因此,它的缺点是每次调用都会创建一个新的zval。这不是特别严重,因此,如果您愿意,请继续。

强制执行zval分隔的原因是,在getInstance中,$instance是一个引用(在=&的意义上,它具有引用计数2(一个用于方法内部的符号,另一个用于静态存储)。由于getInstance不会通过引用返回,因此必须分隔zval -对于返回,将创建一个引用计数为1且引用标记为clear的新值。

PHP getallheaders替代 - php

我正在尝试从服务器上的apache切换到nginx。唯一的问题是我在PHP脚本中使用的getallheaders()函数,该函数不适用于Nginx。我已经尝试过用户在getallheaders函数上的php站点上提供的注释,但这并不返回所有请求标头。请告诉我如何解决这个问题。我真的想切换到Nginx。 参考方案 您仍然可以使用它,但是您必须像这里一样重新定义…

php:是否有充分的理由引用所有数组键/索引? - php

我正在遍历别人的代码,他们总是避免转义其数组键。例如:$ row_rsCatalogsItems [名称]代替$ row_rsCatalogsItems ['名称']因此,我不断地对自己接触的所有事物进行微小的更改,以应对这些惰性。但是现在我想知道这样做是否有很多好处。我得到它会在默认为字符串之前检查常量(我在处理常量时会讨厌php中的行为,因为即使未定义,…

php fopen相对路径断开-神秘 - php

我知道“必须进行某些更改”,但是我的代码似乎整夜无故中断。我的服务器目录结构是这样的: / /脚本 /审计 /其他事情我在“脚本”文件夹中有一个脚本(假设它被称为“ /scripts/MyScript.php”),该脚本使用curl收集网页中的数据,并将其日期过的副本保存在“审核”文件夹中。要写入审核文件夹,我使用了 $ fh = fopen(“ ./ au…

标头和包含项之间有什么区别,应在何处使用 - php

我对两个词感到困惑header ("Location:homepage_php");include("homepage.php");我猜想标题是在检查密码过程后使用的,关于include,您可以在任何地方使用它。但是我不确定它们之间的实际区别是什么以及应该使用这两个中的哪个位置。 参考方案 标头将用户转发到新页面,因此…

Yii,yiic和console - php

在Yii的安装说明中,有必要使用控制台和命令行实用程序-yiic。好吧,在我的共享主机上,我没有SSH访问权限。这就是为什么我有以下问题:我必须多久使用一次控制台?出于什么原因?有办法避免使用Yiic吗?我可以在本地服务器上运行yiic,然后将所有内容传输到最终的Web服务器吗?谢谢! php参考方案 来自Yii论坛的答案:不,您不在生产服务器上使用yiic…