ключевое слово static внутри функции? - PullRequest
100 голосов
/ 31 мая 2011

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

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

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

Ответы [ 7 ]

138 голосов
/ 31 мая 2011

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

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

function doStuff() {
  static $cache = null;

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

  // code using $cache
}

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

69 голосов
/ 10 января 2015

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

Учтите это:

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
13 голосов
/ 31 мая 2011

Учитывая следующий пример:

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

Первый звонок

a(20);

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

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

a(15);

будет выводить 20, а затем установить $v равным 15.

8 голосов
/ 31 мая 2011

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

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

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

3 голосов
/ 31 мая 2011

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

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

?>
2 голосов
/ 26 июля 2016

Расширить на ответ Ян

Если вы расширяете класс статическими переменными, отдельные расширенные классы будут хранить свои «собственные» ссылочные статические значения, которые совместно используются экземплярами.

<?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 <br> один: 4
один : 5 <- x_repeat <br> два : 2

http://ideone.com/W4W5Qv

1 голос
/ 31 мая 2011

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

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

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

...