¿palabra clave `estática` dentro de la función?

110

Estaba mirando la fuente de Drupal 7 y encontré algunas cosas que no había visto antes. Hice una búsqueda inicial en el manual de php, pero no explicó estos ejemplos.

¿Qué le hace la palabra clave statica una variable dentro de una función?

function module_load_all($bootstrap = FALSE) {
    static $has_run = FALSE
usuario151841
fuente

Respuestas:

155

Hace que la función recuerde el valor de la variable dada ( $has_runen su ejemplo) entre múltiples llamadas.

Puede usar esto para diferentes propósitos, por ejemplo:

function doStuff() {
  static $cache = null;

  if ($cache === null) {
     $cache = '%heavy database stuff or something%';
  }

  // code using $cache
}

En este ejemplo, ifsolo se ejecutaría una vez. Incluso si doStuffocurrieran varias llamadas a .

Yoshi
fuente
4
Además, si la función se ha ejecutado una vez, no restablecerá el valor de $cachea nullen llamadas posteriores, ¿verdad?
user151841
7
@ user151841 $cachesolo se restablecerá entre solicitudes. Entonces, sí, no se restablecerá en llamadas posteriores en la misma solicitud (o ejecución del script).
Yoshi
14
@Muhammad porque eso es exactamente lo que hacen las palabras clave estáticas .
Yoshi
2
Creo que la ifverificación de condición $cache === nullse ejecutará cada vez que se llame a esta función, aunque no si $cache = '..'se ejecuta el código de bloque .
Aivaras
¿Qué sucede si la función es un método en una clase, la variable estática se comparte entre instancias?
santiago arizti
83

Parece que nadie mencionó hasta ahora, que las variables estáticas dentro de diferentes instancias de la misma clase siguen siendo su estado. Así que tenga cuidado al escribir código OOP.

Considera esto:

class Foo
{
    public function call()
    {
        static $test = 0;

        $test++;
        echo $test . PHP_EOL; 
    }
}

$a = new Foo();
$a->call(); // 1
$a->call(); // 2
$a->call(); // 3


$b = new Foo();
$b->call(); // 4
$b->call(); // 5

Si desea que una variable estática recuerde su estado solo para la instancia de clase actual, será mejor que se ciña a una propiedad de clase, como esta:

class Bar
{
    private $test = 0;

    public function call()
    {
        $this->test++;
        echo $this->test . PHP_EOL; 
    }
}


$a = new Bar();
$a->call(); // 1
$a->call(); // 2
$a->call(); // 3


$b = new Bar();
$b->call(); // 1
$b->call(); // 2
Yang
fuente
1
¡Ay! Esto me ha mordido más de una vez. Esperaba que la estática se aplicara solo a la instancia, proporcionando memorización; pero esa era una forma incorrecta de pensar, porque "estático" en el contexto de clases significa para la clase como un todo. Propiedades, métodos, Y variables.
systemovich
14

Dado el siguiente ejemplo:

function a($s){
    static $v = 10;
    echo $v;
    $v = $s;
}

Primera llamada de

a(20);

saldrá 10, luego $vserá 20. La variable $vno se recolecta como basura después de que finaliza la función, ya que es una variable estática (no dinámica). La variable permanecerá dentro de su alcance hasta que el script finalice por completo.

Por tanto, la siguiente convocatoria de

a(15);

luego saldrá 20, y luego se configurará $vcomo 15.

mauris
fuente
9

Static funciona de la misma manera que en una clase. La variable se comparte en todas las instancias de una función. En su ejemplo particular, una vez que se ejecuta la función, $ has_run se establece en TRUE. Todas las ejecuciones futuras de la función tendrán $ has_run = TRUE. Esto es particularmente útil en funciones recursivas (como una alternativa a pasar la cuenta).

Una variable estática existe solo en el ámbito de una función local, pero no pierde su valor cuando la ejecución del programa abandona este ámbito.

Ver http://php.net/manual/en/language.variables.scope.php

tofutim
fuente
3

variable estática en una función significa que no importa cuántas veces llame a la función, solo hay 1 variable.

<?php

class Foo{
    protected static $test = 'Foo';
    function yourstatic(){
        static $test = 0;
        $test++;
        echo $test . "\n"; 
    }

    function bar(){
        $test = 0;
        $test++;
        echo $test . "\n";
    }
}

$f = new Foo();
$f->yourstatic(); // 1
$f->yourstatic(); // 2
$f->yourstatic(); // 3
$f->bar(); // 1
$f->bar(); // 1
$f->bar(); // 1

?>
Pwnna
fuente
3

Para ampliar la respuesta de Yang

Si extiende una clase con variables estáticas, las clases extendidas individuales mantendrán su "propia" estática referenciada que se comparte entre instancias.

<?php
class base {
     function calc() {
        static $foo = 0;
        $foo++;
        return $foo;
     }
}

class one extends base {
    function e() {
        echo "one:".$this->calc().PHP_EOL;
    }
}
class two extends base {
    function p() {
        echo "two:".$this->calc().PHP_EOL;
    }
}
$x = new one();
$y = new two();
$x_repeat = new one();

$x->e();
$y->p();
$x->e();
$x_repeat->e();
$x->e();
$x_repeat->e();
$y->p();

salidas:

uno: 1
dos : 1
uno: 2
uno : 3 <- x_repeat
uno: 4
uno : 5 <- x_repeat
dos : 2

http://ideone.com/W4W5Qv

Tschallacka
fuente
1

Dentro de una función, staticsignifica que la variable conservará su valor cada vez que se llame a la función durante la vida útil de la carga de la página.

Por lo tanto, en el ejemplo que ha dado, si llama a una función dos veces, si se establece $has_runen true, entonces la función podría saber que se había llamado anteriormente porque $has_runaún sería igual a truecuando la función se inicia por segunda vez.

El uso de la staticpalabra clave en este contexto se explica en el manual de PHP aquí: http://php.net/manual/en/language.variables.scope.php

Spudley
fuente