且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

实现PHP单例:静态类属性或静态方法变量?

更新时间:2022-12-13 23:08:54

你可能意思是稍微修改(否则我有语法错误):

You probably mean it with a slight modification (I got a syntax error otherwise):

<?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');

这给出:

实例: i>(refcount = 2,is_ref = 1),
对象 Singleton )[ 1 ]

instance: (refcount=2, is_ref=1), object(Singleton)[1]

a:(refcount = 1,is_ref = 0)
i> Singleton )[ 1 ]

a: (refcount=1, is_ref=0), object(Singleton)[1]

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

instance: (refcount=2, is_ref=1), object(Singleton)[1]

b:(refcount = 1,is_ref = 0)
对象 Singleton )[ i> 1 ]

b: (refcount=1, is_ref=0), object(Singleton)[1]

所以它有缺点,每次调用都会创建一个新的zval。这不是特别严重,所以如果你喜欢它,请继续。

So it has the disadvantage a new zval will be created on each call. This is not particularly serious, so if you prefer it, go ahead.

zval分离***的原因是在 getInstance $ instance 是一个引用(在 =& 的意义上,它有引用计数2(一个用于方法中的符号,另一个用于静态存储)由于 getInstance 不会通过引用返回,所以zval必须分开 - 对于返回,创建一个新的引用计数1,引用标志清除。

The reason a zval separation is forced is that inside getInstance, $instance is a reference (in the sense of =&, and it has reference count 2 (one for the symbol inside the method, another for the static storage). Since getInstance doesn't return by reference, the zval must be separated -- for the return, a new one is created with reference count 1 and the reference flag clear.