`static` ключевое слово внутри функции?

Я смотрел на источник для Drupal 7, и я нашел некоторые вещи, которых я раньше не видел. Я сделал некоторые первоначальные взгляды в руководстве php, но это не объясняло эти примеры.

Что делает ключевое слово static для переменной внутри функции?

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

Ответ 1

Он заставляет функцию запоминать значение данной переменной ($has_run в вашем примере) между несколькими вызовами.

Вы можете использовать это для разных целей, например:

function doStuff() {
  static $cache = null;

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

  // code using $cache
}

В этом примере if будет выполняться только один раз. Даже если произойдет несколько вызовов doStuff.

Ответ 2

Похоже, что никто не упоминал до сих пор, что статические переменные внутри разных экземпляров одного и того же класса остаются их состоянием. Поэтому будьте осторожны при написании кода OOP.

Рассмотрим это:

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

Если вы хотите, чтобы статическая переменная помнила свое состояние только для текущего экземпляра класса, вам лучше придерживаться свойства класса, например:

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

Ответ 3

В следующем примере:

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

Первый вызов

a(20);

выведет 10, а затем $v будет 20. Переменная $v не является сборкой мусора после завершения функции, так как это статическая (нединамическая) переменная. Переменная останется в пределах ее объема до тех пор, пока script не закончится полностью.

Следовательно, следующий вызов

a(15);

выдает 20, а затем устанавливает $v как 15.

Ответ 4

Статичность работает так же, как и в классе. Переменная является общей для всех экземпляров функции. В вашем конкретном примере, как только функция запускается, $has_run имеет значение TRUE. Все будущие прогоны функции будут иметь $has_run = TRUE. Это особенно полезно в рекурсивных функциях (в качестве альтернативы передаче счетчика).

Статическая переменная существует только в локальная функция, но она не теряют свою ценность при выполнении программы выходит из этой области.

См. http://php.net/manual/en/language.variables.scope.php

Ответ 5

статическая переменная в функции означает, что независимо от того, сколько раз вы вызываете функцию, существует только одна переменная.

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

?>

Ответ 6

Чтобы расширить на ответ Ян

Если вы расширяете класс со статическими переменными, отдельные расширенные классы будут содержать свой "собственный" статический указатель, который разделяется между экземплярами.

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

выходы:

один: 1
   два: 1
  один: 2
  один: 3 < - x_repeat
  один: 4
  one: 5 < - x_repeat
   два: 2

http://ideone.com/W4W5Qv

Ответ 7

Внутри функции static означает, что переменная будет сохранять свое значение при каждом вызове функции в течение срока службы загрузки страницы.

Поэтому в примере, который вы указали, если вы дважды вызываете функцию, если она устанавливает $has_run в true, тогда функция сможет узнать, что она ранее была вызвана, потому что $has_run все равно будет быть равным true, когда функция запускается во второй раз.

Использование ключевого слова static в этом контексте объясняется в руководстве по PHP здесь: http://php.net/manual/en/language.variables.scope.php