【问题标题】:PHP - Static Local VariablesPHP - 静态局部变量
【发布时间】:2013-10-24 15:13:21
【问题描述】:

所以我最近遇到了这样的代码段:

private static function FOO() {
        static $c = null;
        if ($c == null) {
            $c = new ParentClass_InnerClass();
        }
        return $c;
    }

那么这段代码是怎么回事?这与以下有何不同:

private static $C;

//other methods and fields    

private static function FOO() {
    if(!$self::c) {
        $self::c = new ParentClass_InnerClass();
    }
    return $self::c;
}

或者它们甚至是同一个概念?

【问题讨论】:

  • 第二个例子在技术上是不正确的。应该是self::$cstatic::$c
  • PHP: Variable scope - Manual阅读更多关于静态局部变量的信息
  • @ComFreek 哎呀,是的。
  • $c == null!$c 不完全一样,是吗?
  • @SimonAndréForsberg 在这种情况下你是什么意思?这不像 $c 永远是布尔假。你真的在挑剔一段与问题无关的代码。

标签: php static


【解决方案1】:

它们本质上是相同的概念,尽管范围不同:

class Foobar
{
    private static $c = null;
    public static function FOO()
    {
        if (self::$c === null)
        {
            self::$c = new stdClass;
        }
        return self::$c;
    }
    public static function checkC()
    {
        if (self::$c === null)
        {
            return false;
        }
        return self::$c;
    }
}

Foobar::checkC();//returns false, as $c is null
//function checkC has access to $c
$returned = Foobar::FOO();//returns object
if ($returned === Foobar::checkC())
{//will be true, both reference the same variable
    echo 'The same';
}

然而,如果我们将代码更改为:

class Foobar
{
    public static function FOO()
    {
        static $c = null;
        if ($c === null)
        {
            $c = new stdClass;
        }
        return $c;
    }
    public static function checkC()
    {
        if ($c === null)
        {
            return false;
        }
        return $c;
    }
}

调用checkC时会收到提示:未定义变量。静态变量 $c 只能从 FOO 范围内访问。私有属性的范围是整个类。真的是这样。
但实际上,帮自己一个忙:仅在需要时才使用静态(它们也在实例之间共享)。而在 PHP 中,您实际上很少需要静态。

【讨论】:

  • 嗨!我明白了,但我不得不问为什么每次调用 FOO() 时它都不会重置 $c = null?提前致谢
  • @sale108 5 年没有使用 PHP,但是声明为 static 的函数中的变量会在内存中创建一个 zval,无论您在声明/初始化语句中为其分配什么值.无论zval 发生了什么,接下来都会更新内存中的同一个对象。本质上,将static $c = null; 视为执行一次,然后在后续调用中跳过
  • 谢谢!这足以让我自己调查:)
【解决方案2】:

它们是相同的概念,除了在第一个代码块中,静态变量是函数的局部变量,这样的静态变量可以在任何函数中使用,甚至在类的上下文之外:

function test() {
    static $counter = 0;
    return $counter++;
}

echo test(); // 0
echo test(); // 1

【讨论】:

  • 怎么样?它是一个私人功能。您的意思是另一个公共函数可以将变量传递出去?
  • 不,这种变量是函数的局部变量,不能在函数之外使用。我的意思是你可以在任何函数中使用静态变量,即使它不是类方法。
  • 我用一个简单函数中的示例更新了我的答案,在一个类之外。
【解决方案3】:

在顶部示例中,您只能从本地范围 (FOO()) 访问 $c,在底部示例中,您可以从整个类访问 $c,因此不仅可以形成 FOO()

【讨论】:

  • 所以它强制一个私有变量的单例模式,但是由于它强制你通过FOO()你保证它被初始化了吗?
  • @thatidiotguy: 是的,但是强制初始化一个类也可以使用工厂模式,以及使用构造函数和new 关键字 Don't use singletons
猜你喜欢
  • 1970-01-01
  • 2018-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-04
  • 2012-06-06
  • 1970-01-01
  • 2018-04-18
相关资源
最近更新 更多