【问题标题】:PHP and Static Variables in Object Member Functions对象成员函数中的 PHP 和静态变量
【发布时间】:2011-09-29 20:54:06
【问题描述】:

直到今天,我都认为我对静态修饰符的工作原理有了相当好的了解。我知道(通俗地说)函数中的静态变量不会在对该函数的调用中“重置”,并且我知道类上的静态变量和函数可以通过类本身调用它们来访问(不是实例化)类)。

我的问题是这样的:今天我发现如果我在一个类上声明一个非静态函数的静态变量inside,该类的所有实例化都共享单独调用成员函数中的静态变量。

例如:

class A {
    public function GetValue() {
        static $value = 0;
        $value++;
        return $value;
    }
}

$instance_1 = new A();
$instance_2 = new A();
echo $instance_1->GetValue();
echo $instance_1->GetValue();

echo $instance_2->GetValue();
echo $instance_2->GetValue();

echo $instance_1->GetValue();
echo $instance_1->GetValue();

请注意,GetValue 函数既没有声明为静态函数,也没有以静态方式使用(如在类本身上调用)。

现在,我一直认为这会输出:121234

相反,我发现它会输出:123456

就像我说的,如果静态变量 $value 在静态函数内部,我会理解这一点。但是,由于它位于非静态函数中,我只是假设它只会“绑定”到每个单独实例化中的函数。

我想我的问题是双重的,那么...... 1)这是一个错误还是预期的行为? 2) 其他语言是否以相同的方式处理这些“非静态中的静态”变量,还是 PHP 独有的?

【问题讨论】:

  • 我已经看到几个关于 PHP 中 static 行为的问题。似乎这是一个缺乏文档的领域 - 无论是数量还是质量。
  • (参考) static variables
  • 那太糟糕了。我认为在这种情况下“静态”意味着不会为这个“对象”重置变量,但不会为“类”重置。再次是反直觉的行为。如果在其他语言中行为相同 - 他们都只是愚蠢的白痴。这个方法不是静态的,所以方法属于对象实例。变量属于方法,所以变量应该只属于对象,不属于类。啊……
  • @Gordon:公平地说,在再次查看该链接之后(我最初是这样做的),我可以找到解决此特殊情况的“最新”评论日期为 2005 年 12 月 13 日08:22 :)
  • @OZ_:您以错误的方式考虑成员函数。在下面阅读我的答案...

标签: php static


【解决方案1】:

我从 Josh Duck 的这篇文章中复制了以下信息:http://joshduck.com/blog/2010/03/19/exploring-phps-static-scoping/

静态变量从 PHP 4 开始就可以使用,它允许您定义一个只能从当前函数访问的持久变量。这允许您将状态封装到函数或方法中,并且可以消除对单个函数就足够的类的需求。

在类方法中定义静态变量时,它们将始终引用调用该方法的类。在这样做时,它们的行为几乎类似于通过静态引用的属性,尽管存在细微差别。

静态变量不能保留调用类范围。如果您有一个包含从其类内部和外部调用的静态变量的继承方法,这可能会出现问题。

【讨论】:

    【解决方案2】:
    1. 这是意料之中的。
    2. 在 C++(可能还有其他)中也是如此。

    您应该将非静态类成员函数视为就像普通函数一样,但具有由解释器自动提供的隐式 $this 参数。 (这正是它们在大多数语言中的实现方式。)

    【讨论】:

      【解决方案3】:

      据我所知,所有带有静态变量的语言都以这种方式对待它们。将静态变量视为只能从特定范围访问的全局变量。

      【讨论】:

      • 虽然我喜欢这种看待方式,但我认为我仍然很固执地说我认为首先不应该这样做:s
      • 如果您想要一个变量在类方法调用中保持其值,@Narcissus,只需使用标准成员变量。
      • 大部分时间我都这样做,但我喜欢一个函数能够缓存自己的结果以便稍后返回的想法,如果这有意义的话,缓存不会污染类本身。
      猜你喜欢
      • 2011-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-20
      • 1970-01-01
      相关资源
      最近更新 更多