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

Nar*_*sus 16 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();
Run Code Online (Sandbox Code Playgroud)

请注意,GetValue函数既未声明为静态函数,也未以静态方式使用(如在类本身中调用).

现在,我总是认为这会输出:121234

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

就像我说的,如果静态变量$ value在静态函数中,我会理解这一点.然而,由于它在非静态函数中,我只是假设它只与每个单独实例化中的函数"绑定".

我想我的问题是双重的,然后...... 1)这是一个错误还是预期的行为?2)其他语言是否以相同的方式对待这些"静态非静态"变量,或者这对PHP来说是独一无二的?

Oli*_*rth 7

  1. 这是预料之中的.
  2. 在C++中也是如此(也可能是其他的).

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


Bru*_*lva 5

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

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

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

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