PHP y variables estáticas en las funciones miembro de objeto

Hasta hoy, pensé que tenía una idea bastante buena de cómo funcionaba el modificador estático. Sé que (en términos simples) una variable estática en una función no se “restablece” en llamadas a esa función, y sé que se puede acceder a las variables y funciones estáticas en una clase invocandolas a través de la clase (no una instanciación) de la clase).

Mi problema es el siguiente: hoy descubrí que si declaro una variable estática dentro de una función no estática en una clase, todas las instancias de esa clase comparten esa variable estática en llamadas separadas a la función miembro.

Por ejemplo:

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(); 

Tenga en cuenta que la función GetValue no se declara estática ni se usa de forma estática (como en, llamada en la propia clase).

Ahora, siempre asumí que esto produciría: 121234

En cambio, me parece que saldrá: 123456

Como digo, lo entendería si la variable estática $ value estuviera dentro de una función estática. Sin embargo, al estar dentro de una función no estática, asumí que solo estaría ‘atada’ a la función ‘dentro’ de cada instanciación individual.

Supongo que mi pregunta es doble, entonces … 1) ¿Es esto un error o un comportamiento esperado? 2) ¿otros idiomas tratan estas variables “estáticas dentro de no estáticas” de la misma manera, o esto es exclusivo de PHP?

  1. Esto es esperado.
  2. Este también es el caso en C ++ (y probablemente también en otros).

Debería pensar en las funciones de los miembros de la clase no estáticos como si fueran simplemente funciones comunes, pero con un $this implícito $this argumento que proporciona automáticamente el intérprete. (Así es exactamente como se implementan en la mayoría de los idiomas).

Copié la siguiente información de este artículo de Josh Duck: http://joshduck.com/blog/2010/03/19/exploring-phps-static-scoping/

Las variables estáticas han estado disponibles desde PHP 4 y le permiten definir una variable persistente a la que solo se puede acceder desde la función actual. Esto le permite encapsular estado en una función o método y puede eliminar la necesidad de clases donde una sola función sea suficiente.

Cuando se define una variable estática dentro de un método de clase, siempre se referirán a la clase a la que se llamó el método. Al hacer esto, actúan casi como propiedades referenciadas a través de estática, aunque hay diferencias sutiles.

Las variables estáticas no pueden preservar el scope de la clase llamante. Esto puede ser potencialmente problemático si tiene un método heredado que contiene una variable estática que se llama tanto desde dentro como desde fuera de su clase.

Hasta donde yo sé, todos los idiomas con variables estáticas los tratan de esta manera. Considere las variables estáticas como variables globales a las que solo se puede acceder desde un determinado ámbito.