2011-07-06 26 views
13

Hasta hoy, creía tener un buen conocimiento 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).PHP y variables estáticas en las funciones de miembro de objeto

Mi problema es el siguiente: hoy he encontrado que si declara una variable estática dentro de una función no estático 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(); 

en cuenta que la función GetValue no es ni declara como estática o utilizar de una manera estática (como en, pidió a la clase misma).

Ahora, siempre asumí que esto seria: 121234

En su lugar, me parece que seria: 123456

Como digo, me entiende esto si el valor de $ variable estática estaba 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?

+0

He visto varias preguntas sobre SO sobre el comportamiento de 'static' en PHP. Parecería que este es un área que carece de documentación, ya sea en cantidad o calidad. –

+0

* (referencia) * [variables estáticas] (http://php.net/manual/en/language.variables.scope.php#language.variables.scope.static) – Gordon

+0

eso es chupe. Pensé que "estático" en este caso significa que la variable no se restablecerá para este "objeto", pero no para la "clase". Nuevamente comportamiento anti-intuitivo. Y si en otros idiomas el comportamiento es el mismo, todos son idiotas estúpidos. Este método no es estático, por lo que el método pertenece a la instancia del objeto. La variable pertenece al método, por lo que la variable debe pertenecer solo al objeto, no a la clase. Ahh ... –

Respuesta

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

usted debe pensar en funciones miembro de clase no estáticos como si fueran igual que las funciones ordinarias, pero con un argumento implícito $this que se proporciona de forma automática por el intérprete. (Así es exactamente como se implementan en la mayoría de los idiomas.)

1

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.

+0

Aunque me gusta esta forma de ver, creo que todavía soy lo suficientemente testaruda como para decir que no creo que deba hacerse de esta manera en primer lugar: s – Narcissus

+0

Si desea una variable que mantenga su valor en toda la clase invocaciones de método, @Narcissus, solo usa una variable de miembro estándar. –

+0

la mayor parte del tiempo lo hago, pero me gustó la idea de que una función sea capaz de almacenar en caché sus propios resultados para volver más tarde, sin que ese caché contamine la clase en sí, si eso tiene sentido. – Narcissus

4

He copiado la siguiente información de este artículo por 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 que sólo 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 en la que se invocó 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 conservar el alcance 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.

Cuestiones relacionadas