Parola chiave `statica` all'interno della funzione?


110

Stavo cercando la fonte per Drupal 7 e ho trovato alcune cose che non avevo visto prima. Ho fatto qualche ricerca iniziale nel manuale di php, ma non ha spiegato questi esempi.

Cosa fa la parola chiave statica una variabile all'interno di una funzione?

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

Risposte:


155

Fa in modo che la funzione ricordi il valore della variabile data ( $has_runnel tuo esempio) tra più chiamate.

Potresti usarlo per scopi diversi, ad esempio:

function doStuff() {
  static $cache = null;

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

  // code using $cache
}

In questo esempio, ifverrebbe eseguito solo una volta. Anche se doStuffsi verificassero più chiamate a .


4
Inoltre, se la funzione è stata eseguita una volta, non reimposterà il valore di $cachea nullnelle chiamate successive, giusto?
user151841

7
@ user151841 $cacheverrà reimpostato solo tra le richieste. Quindi sì, non verrà ripristinato su chiamate successive nella stessa richiesta (o esecuzione dello script).
Yoshi

14
@ Muhammad perché è proprio quello che fanno le parole chiave statiche .
Yoshi

2
Credo che il ifcontrollo delle condizioni $cache === nullverrebbe eseguito ogni volta che viene chiamata questa funzione, anche se il codice del blocco non $cache = '..'sarebbe stato eseguito.
Aivaras

cosa succede se la funzione è un metodo in una classe, la variabile statica è condivisa tra le istanze?
santiago arizti

83

Sembra che nessuno abbia menzionato finora che le variabili statiche all'interno di istanze diverse della stessa classe rimangono il loro stato. Quindi fai attenzione quando scrivi codice OOP.

Considera questo:

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

Se vuoi che una variabile statica ricordi il suo stato solo per l'istanza di classe corrente, è meglio attenersi a una proprietà di classe, come questa:

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

1
Ahia! Questo mi ha morso più di una volta. Mi aspettavo che la statica si applicasse solo all'istanza, fornendo la memoizzazione; ma quello era un modo di pensare sbagliato, perché "statico" nel contesto delle classi significa per la classe nel suo insieme. Proprietà, metodi e variabili AND.
systemovich

14

Dato il seguente esempio:

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

Prima chiamata di

a(20);

verrà prodotto 10, quindi $vessere 20. La variabile$v non viene raccolta in Garbage Collection al termine della funzione, poiché è una variabile statica (non dinamica). La variabile rimarrà nel suo ambito fino al termine dello script.

Pertanto, la seguente chiamata di

a(15);

verrà quindi emesso 20e quindi impostato $vsu 15.


9

Statico funziona allo stesso modo di una classe. La variabile è condivisa tra tutte le istanze di una funzione. Nel tuo esempio particolare, una volta eseguita la funzione, $ has_run è impostato su TRUE. Tutte le esecuzioni future della funzione avranno $ has_run = TRUE. Ciò è particolarmente utile nelle funzioni ricorsive (in alternativa al passaggio del conteggio).

Una variabile statica esiste solo nell'ambito di una funzione locale, ma non perde il suo valore quando l'esecuzione del programma esce da questo ambito.

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


3

variabile statica in una funzione significa che non importa quante volte chiami la funzione, c'è solo 1 variabile.

<?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

?>

3

Per espandere la risposta di Yang

Se estendi una classe con variabili statiche, le singole classi estese manterranno il loro "proprio" riferimento statico condiviso tra le istanze.

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

uscite:

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

http://ideone.com/W4W5Qv


1

All'interno di una funzione, static significa che la variabile manterrà il suo valore ogni volta che la funzione viene chiamata durante la vita del caricamento della pagina.

Quindi nell'esempio che hai dato, se chiami una funzione due volte, se è impostata $has_runa true, allora la funzione potrebbe sapere che era stata chiamata in precedenza perché $has_runsarebbe ancora uguale a truequando la funzione inizia la seconda volta.

L'utilizzo della staticparola chiave in questo contesto è spiegato nel manuale PHP qui: http://php.net/manual/en/language.variables.scope.php

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.