Variables estáticas de PHP

7 minutos de lectura

avatar de usuario
dios mío

$count = 5;
function get_count()
{
    static $count = 0;
    return $count++;
}
echo $count;
++$count;
echo get_count();
echo get_count();

Supuse que da como resultado 5 0 1 y es correcto, pero necesito una mejor explicación.

  • Si esto es tarea, etiquétala como tal.

    –Paul McMillan

    29 de octubre de 2009 a las 8:50

  • No creo que sea tarea, algunas personas simplemente nunca han usado variables estáticas en PHP (especialmente si están acostumbradas a la programación de procedimientos directos)

    – Tim Publicar

    29 de octubre de 2009 a las 8:55

  • ¿Cuál es la cuenta ++$; haciendo ahí?

    – Alix Axel

    29 de octubre de 2009 a las 9:57

  • el nombre de $count es engañoso. el $conteo dentro de la función no es lo mismo que el $conteo externo. ¿Estás creando una prueba de algo?

    – Elzo Valugui

    29 de octubre de 2009 a las 13:01

  • Esto suena principalmente como una pregunta de entrevista en lugar de una tarea.

    – giannis christofakis

    21 de junio de 2014 a las 13:54

avatar de usuario
fusión del alma

La variable $count en la función no está relacionado de ninguna manera con el global $count variable. los static palabra clave es lo mismo que en C o Java, significa: Inicializar esta variable solo una vez y mantener su estado cuando finalice la función. Esto significa que, cuando la ejecución vuelve a ingresar a la función, ve que el conteo interno de $ ya se inicializó y almacenó la última vez como 1y usa ese valor.

$count = 5; // "outer" count = 5

function get_count()
{
    static $count = 0; // "inner" count = 0 only the first run
    return $count++; // "inner" count + 1
}

echo $count; // "outer" count is still 5 
++$count; // "outer" count is now 6 (but you never echoed it)

echo get_count(); // "inner" count is now + 1 = 1 (0 before the echo)
echo get_count(); // "inner" count is now + 1 = 2 (1 before the echo)
echo get_count(); // "inner" count is now + 1 = 3 (2 before the echo)

Espero que esto aclare tu mente.

avatar de usuario
torarina

Tiene dos variables separadas que se llaman $count, pero tienen un diferente alcance. La primera variable no se declara explícitamente, pero aparece cuando la asigna por primera vez.

La segunda variable (dentro del método) solo es visible para ese método. Desde su estático, su valor se conserva entre varias ejecuciones del mismo método. La asignación $count = 0; solo se ejecuta la primera vez que se ejecuta el método.

En cuanto al operador de incremento (++), el resultado de la evaluación es el valor antes de se incrementó, porque el (unario) viene después del nombre de la variable. Entonces sí, la salida sería 5, 0, 1.
Si fueras a escribir return ++$count;el resultado hubiera sido 5, 1, 2.

Nota la ++$count tiene en su código existente, es efectivamente equivalente a $count++, ya que se descarta el resultado de la evaluación. El efecto a la $count variable es la misma: se incrementa en 1.

  • Horray, alguien finalmente dijo ‘alcance’ 🙂

    – Tim Publicar

    29 de octubre de 2009 a las 8:57

Primer eco: te da la variable $count que declaras en tu primera línea.

Segundo eco: llamadas get_count que crea la variable estática $count (por lo que está en contexto para esta función) y cuando crea una instancia de la variable estática, la establece en cero. return $count++ es una de esas líneas que generalmente evitamos en el código, pero esencialmente, se incrementa DESPUÉS de que se devuelve el valor.

Tercer eco: Del mismo modo, 0 se incrementó a 1 después de la llamada anterior a get_count, lo mismo sucede aquí: devuelve 1 e incrementa el valor a 2.

¿Eso ayuda o es realmente más confuso?

avatar de usuario
Alex Míznikov

PHP tiene un bien conocido static palabra clave que se usa ampliamente en PHP orientado a objetos para definir métodos y propiedades estáticos, pero se debe tener en cuenta que static también se puede usar dentro de funciones para definir variables estáticas.

¿Qué es una ‘variable estática’?

Una variable estática se diferencia de una variable ordinaria definida en el ámbito de la función en que no pierde su valor cuando la ejecución del programa sale de este ámbito. Consideremos el siguiente ejemplo de uso de variables estáticas:

function countSheep($num) {
   static $counter = 0;
   $counter += $num;
   echo "$counter sheep jumped over fence";
}

countSheep(1);
countSheep(2);
countSheep(3);

Resultado:

1 sheep jumped over fence
3 sheep jumped over fence
6 sheep jumped over fence

Si hubiéramos definido $counter sin que static entonces cada vez que el valor repetido sería el mismo que $num parámetro pasado a la función. Usando static permite construir este contador simple sin una solución adicional.

Casos de uso de variables estáticas

  1. Almacenar valores entre llamadas posteriores a la función.
  2. Para almacenar valores entre llamadas recursivas cuando no hay forma (o propósito) de pasarlos como parámetros.
  3. Para almacenar en caché el valor que normalmente es mejor recuperar una vez. Por ejemplo, el resultado de leer un archivo inmutable en el servidor.

Trucos

Una variable estática existe solo en el ámbito de una función local. No se puede acceder fuera de la función en la que se ha definido. Por lo tanto, puede estar seguro de que mantendrá su valor sin cambios hasta la próxima llamada a esa función.

Desde PHP 5.6, una variable estática solo puede definirse como escalar o como expresión escalar. Asignarle otros valores conduce inevitablemente a una falla (al menos en el momento en que se escribió este artículo).

Sin embargo, puede hacerlo solo en la siguiente línea de su código:

function countSheep($num) {
    static $counter = 0;
    $counter += sqrt($num);//imagine we need to take root of our sheep each time
    echo "$counter sheep jumped over fence";
}

Resultado:

2 sheep jumped over fence
5 sheep jumped over fence
9 sheep jumped over fence

Una función estática es un poco ‘compartida’ entre métodos de objetos de la misma clase. Es fácil de entender viendo el siguiente ejemplo:

class SomeClass {
    public function foo() {
        static $x = 0;
        echo ++$x;
    }
}

$object1 = new SomeClass;
$object2 = new SomeClass;

$object1->foo(); // 1
$object2->foo(); // 2 oops, $object2 uses the same static $x as $object1
$object1->foo(); // 3 now $object1 increments $x
$object2->foo(); // 4 and now his twin brother

Esto solo funciona con objetos de la misma clase. Si los objetos son de diferentes clases (incluso se extienden entre sí), el comportamiento de las variables estáticas será el esperado.

¿Es la variable estática la única forma de mantener los valores entre las llamadas a una función?

Otra forma de mantener valores entre llamadas a funciones es usar cierres. Los cierres se introdujeron en PHP 5.3. En dos palabras, le permiten limitar el acceso a un conjunto de variables dentro del alcance de una función a otra función anónima que será la única forma de acceder a ellas. Estar en las variables de cierre puede imitar (con más o menos éxito) conceptos OOP como ‘constantes de clase’ (si se pasaron en el cierre por valor) o ‘propiedades privadas’ (si se pasaron por referencia) en programación estructurada.

Este último en realidad permite usar cierres en lugar de variables estáticas. Qué usar siempre depende del desarrollador para decidir, pero debe mencionarse que las variables estáticas son definitivamente útiles cuando se trabaja con recursiones y merecen ser notadas por los desarrolladores.

avatar de usuario
Maximiliano Mayerl

Bueno, antes que nada, $contar dentro de la función y $contar fuera de la función son 2 variables diferentes. Eso explica por qué la primera salida imprime 5.

Ahora para lo estático: estático significa que su variable local se crea solo una vez, cuando la función se ejecuta por primera vez. Cada ejecución posterior de la función usa la misma variable, por lo que los últimos valores de la variable en la última ejecución de la función todavía están allí.

Entonces, cuando llama por primera vez a get_count(), la variable se establece en 0 y luego se devuelve. Después del retorno, la variable se incrementa.

Cuando llama a la función por segunda vez, la variable sigue siendo 1. Este valor se devuelve y luego se incrementa a 2.

¿Ha sido útil esta solución?