Schlüsselwort `static` in Funktion?

109

Ich habe nach der Quelle für Drupal 7 gesucht und einige Dinge gefunden, die ich vorher noch nicht gesehen hatte. Ich habe einen ersten Blick in das PHP-Handbuch geworfen, aber es hat diese Beispiele nicht erklärt.

Was macht das Schlüsselwort staticmit einer Variablen innerhalb einer Funktion?

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

Antworten:

155

Dadurch merkt sich die Funktion den Wert der angegebenen Variablen ( $has_runin Ihrem Beispiel) zwischen mehreren Aufrufen.

Sie können dies für verschiedene Zwecke verwenden, zum Beispiel:

function doStuff() {
  static $cache = null;

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

  // code using $cache
}

In diesem Beispiel ifwürde das nur einmal ausgeführt. Auch wenn mehrere Anrufe an doStuffauftreten würden.

Yoshi
quelle
4
Auch wenn die Funktion einmal ausgeführt hat, wird es nicht den Wert zurückgesetzt , $cacheum nullauf spätere Anrufe, nicht wahr?
user151841
7
@ user151841 $cachewird nur zwischen Anforderungen zurückgesetzt. Ja, es wird nicht bei späteren Aufrufen in derselben Anforderung (oder Ausführung des Skripts) zurückgesetzt.
Yoshi
14
@ Muhammad, weil das genau das ist, was die statischen Schlüsselwörter tun .
Yoshi
2
Ich glaube if, dass die Bedingungsprüfung $cache === nulljedes Mal ausgeführt wird, wenn diese Funktion aufgerufen wird, und nicht, ob der Blockcode $cache = '..'ausgeführt wird.
Aivaras
Was passiert, wenn die Funktion eine Methode in einer Klasse ist? Wird die statische Variable von Instanzen gemeinsam genutzt?
Santiago Aristi
83

Es scheint, als hätte bisher niemand erwähnt, dass statische Variablen in verschiedenen Instanzen derselben Klasse ihren Zustand behalten. Seien Sie also vorsichtig, wenn Sie OOP-Code schreiben.

Bedenken Sie:

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

Wenn Sie möchten, dass sich eine statische Variable ihren Status nur für die aktuelle Klasseninstanz merkt, sollten Sie sich an eine Klasseneigenschaft wie die folgende halten:

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
quelle
1
Autsch! Das hat mich mehr als einmal gebissen. Ich habe erwartet, dass die Statik nur für die Instanz gilt und Memoisierung bereitstellt. aber das war eine falsche Denkweise, denn "statisch" im Kontext von Klassen bedeutet für die Klasse als Ganzes. Eigenschaften, Methoden UND Variablen.
Systemovich
14

Anhand des folgenden Beispiels:

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

Erster Anruf von

a(20);

wird ausgegeben 10, dann $vzu sein 20. Die Variable $vwird nach Beendigung der Funktion nicht als Müll gesammelt, da es sich um eine statische (nicht dynamische) Variable handelt. Die Variable bleibt in ihrem Bereich, bis das Skript vollständig beendet ist.

Daher der folgende Aufruf von

a(15);

wird dann ausgegeben 20und dann $vauf sein gesetzt 15.

Mauris
quelle
9

Statisch funktioniert genauso wie in einer Klasse. Die Variable wird von allen Instanzen einer Funktion gemeinsam genutzt. In Ihrem Beispiel wird $ has_run nach dem Ausführen der Funktion auf TRUE gesetzt. Alle zukünftigen Läufe der Funktion haben $ has_run = TRUE. Dies ist besonders nützlich bei rekursiven Funktionen (als Alternative zum Übergeben der Zählung).

Eine statische Variable existiert nur in einem lokalen Funktionsbereich, verliert jedoch nicht ihren Wert, wenn die Programmausführung diesen Bereich verlässt.

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

tofutim
quelle
3

Eine statische Variable in einer Funktion bedeutet, dass unabhängig davon, wie oft Sie die Funktion aufrufen, nur eine Variable vorhanden ist.

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

Um die Antwort von Yang zu erweitern

Wenn Sie eine Klasse mit statischen Variablen erweitern, enthalten die einzelnen erweiterten Klassen ihre "eigene" statische Referenz, die von Instanzen gemeinsam genutzt wird.

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

Ausgänge:

eins: 1
zwei : 1
eins: 2
eins : 3 <- x_wiederholung
eins: 4
eins : 5 <- x_wiederholung
zwei : 2

http://ideone.com/W4W5Qv

Tschallacka
quelle
1

Innerhalb einer Funktion, static bedeutet dies, dass die Variable ihren Wert jedes Mal beibehält, wenn die Funktion während der Lebensdauer des Seitenladens aufgerufen wird.

Wenn Sie in dem von Ihnen angegebenen Beispiel eine Funktion zweimal aufrufen, wenn sie auf gesetzt ist $has_run, truekann die Funktion daher erkennen, dass sie zuvor aufgerufen wurde, da $has_runsie immer noch truedem Zeitpunkt entspricht, zu dem die Funktion zum zweiten Mal gestartet wird.

Die Verwendung des staticSchlüsselworts in diesem Zusammenhang wird im PHP-Handbuch hier erläutert: http://php.net/manual/en/language.variables.scope.php

Spudley
quelle