函数内部的静态变量不能保持对单例的引用 [英] Static variable inside function can't hold reference to singleton

查看:147
本文介绍了函数内部的静态变量不能保持对单例的引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到PHP中有一个单身人士的奇怪行为,没有更好的方法来解释这个,但有一个例子。



假设我有以下单例类:

  class Singleton 
{
protected function __construct()
{
/ /拒绝直接实例!
}
保护函数__clone()
{
//拒绝克隆!

public static function& Instance()
{
static $ Instance;

echo'Class Echo'.PHP_EOL;
var_dump($ Instance);

if(!isset($ Instance)){
$ Instance = new self;
}

返回$实例;


$ / code $ / pre

以下函数:

 函数Test($ Init = FALSE)
{
static $ Instance;

if($ Init === TRUE&&!isset($ Instance)){
$ Instance =&单::实例();
}

echo'Function Echo'.PHP_EOL;
var_dump($ Instance);

返回$ Instance;
}

而且当我使用以下内容时:

  Test(TRUE); 
Test();
Singleton :: Instance();

输出结果为:

 类Echo 
NULL
函数Echo
object(Singleton)#1(0){
}
函数Echo
NULL
Class Echo
object(Singleton)#1(0){
}

正如你所看到的那样,即使变量是静态的,在函数内部保存的引用在执行后也会丢失。同时注意到,类方法中的静态变量正常工作。



这应该是正常的,或者我做错了什么?

解决方案

这种行为是有文件记录


Zend引擎1驱动PHP 4,实现 static and global 修饰符用于参考资料。例如,使用全局语句在函数范围内导入的真正的全局变量实际上会创建对全局变量的引用。这可能会导致意外的行为。


这种行为没有改变,因为ZE1和解决方案仅仅是不分配参考静态变量,所以:

  $ Instance = Singleton :: Instance(); 

更新
<我已经简化了下面的问题:

$ p $ function test2($ init = false,$ value = null)
{
static $ test;

if($ init){
$ test =& $值;
}

var_dump($ test);
}

$ v = 1;

test2(true,$ v);
test2();

输出:

  int(1)
NULL


I've noticed a weird behavior with singletons in PHP there's no better way to explain this but with an example.

Let's say I have the following singleton class:

class Singleton
{
    protected function __construct()
    {
        // Deny direct instantion!
    }
    protected function __clone()
    {
        // Deny cloning!
    }
    public static function &Instance()
    {
        static $Instance;

        echo 'Class Echo'.PHP_EOL;
        var_dump($Instance);

        if (!isset($Instance)) {
            $Instance = new self;
        }

        return $Instance;
    }
}

And the following function:

function Test($Init = FALSE)
{
    static $Instance;

    if ($Init === TRUE && !isset($Instance)) {
        $Instance =& Singleton::Instance();
    }

    echo 'Function Echo'.PHP_EOL;
    var_dump($Instance);

    return $Instance;
}

And when I use the following:

Test(TRUE);
Test();
Singleton::Instance();

The output is:

Class Echo
NULL
Function Echo
object(Singleton)#1 (0) {
}
Function Echo
NULL
Class Echo
object(Singleton)#1 (0) {
}

As you can see the saved reference inside the function is lost after the execution even though the variable is static Also notice that the static variable inside the class method is working fine.

Is this supposed to be normal or I'm doing something wrong?

解决方案

This behaviour is documented:

The Zend Engine 1, driving PHP 4, implements the static and global modifier for variables in terms of references. For example, a true global variable imported inside a function scope with the global statement actually creates a reference to the global variable. This can lead to unexpected behaviour.

This behaviour hasn't changed since ZE1 and the solution is simply to not assign a reference to a static variable, so:

$Instance = Singleton::Instance();

Update

I've simplified the issue below:

function test2($init = false, $value = null)
{
  static $test;

  if ($init) {
    $test =& $value;
  }

  var_dump($test);
}

$v = 1;

test2(true, $v);
test2();

Output:

int(1)
NULL

这篇关于函数内部的静态变量不能保持对单例的引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆