对象成员函数中的PHP和静态变量

时间:2011-07-06 18:13:37

标签: php static

直到今天,我还以为我对静态修饰符的工作方式有了很好的把握。我知道(在非专业术语中)函数中的静态变量不会在对该函数的调用中“重置”,并且我知道类上的静态变量和函数可以通过类本身调用它们来访问(不是实例化)该课程。)

我的问题是:今天我发现如果我在一个类上声明一个非静态函数的里面的静态变量,那么该类的所有实例都会共享单独调用成员函数时的静态变量。

例如:

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来说是独一无二的?

3 个答案:

答案 0 :(得分:7)

  1. 这是预期的。
  2. C ++也是如此(也可能是其他人)。
  3. 您应该将非静态类成员函数视为普通函数,但使用由解释器自动提供的隐式$this参数。 (这正是他们在大多数语言中实施的方式。)

答案 1 :(得分:5)

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

  

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

     

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

     

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

答案 2 :(得分:2)

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