Статические переменные PHP - PullRequest
       36

Статические переменные PHP

41 голосов
/ 29 октября 2009
$count = 5;
function get_count()
{
    static $count = 0;
    return $count++;
}
echo $count;
++$count;
echo get_count();
echo get_count();

Я догадался, что выводит 5 0 1, и это правильно, но мне нужно лучшее объяснение?

Ответы [ 6 ]

71 голосов
/ 29 октября 2009

Переменная $count в функции никак не связана с глобальной переменной $count. Ключевое слово static такое же, как в C или Java, это означает: инициализируйте эту переменную только один раз и сохраняйте ее состояние после завершения функции. Это означает, что когда выполнение повторно входит в функцию, оно видит, что внутренний $ count уже был инициализирован и сохранен в последний раз как 1, и использует это значение.

41 голосов
/ 29 октября 2009
$count = 5; // "outer" count = 5

function get_count()
{
    static $count = 0; // "inner" count = 0 only the first run
    return $count++; // "inner" count + 1
}

echo $count; // "outer" count is still 5 
++$count; // "outer" count is now 6 (but you never echoed it)

echo get_count(); // "inner" count is now + 1 = 1 (0 before the echo)
echo get_count(); // "inner" count is now + 1 = 2 (1 before the echo)
echo get_count(); // "inner" count is now + 1 = 3 (2 before the echo)

Надеюсь, это очистит ваш разум.

13 голосов
/ 29 октября 2009

У вас есть две отдельные переменные, которые называются $ count, но они имеют различную область действия . Первая переменная не объявлена ​​явно, но возникает при первом ее назначении.

Вторая переменная (внутри метода) видна только этому методу. Так как static , его значение сохраняется между несколькими выполнениями одного и того же метода. Назначение $count = 0; выполняется только при первом запуске метода.

Что касается оператора приращения (++), результатом вычисления является значение до того, как было увеличено, поскольку оператор ( унарный ) следует после имени переменной. Так что да, результат будет 5, 0, 1.
Если бы вы написали return ++$count;, результат был бы 5, 1, 2.

Примечание: ++$count, который вы имеете в существующем коде, фактически эквивалентен $count++, так как результат оценки отбрасывается. Эффект для переменной $count тот же: он увеличивается на 1.

5 голосов
/ 29 октября 2009

Первое эхо: выдает переменную $ count, которую вы объявляете в первой строке.

Второе эхо: calles get_count, который создает статическую переменную $ count (так что она находится в контексте этой функции), а когда вы создаете экземпляр статической переменной, вы устанавливаете ее в ноль. return $ count ++ - это одна из тех строк, которые мы обычно избегаем в коде, но, по сути, она увеличивается после того, как возвращается значение.

Третий эхо: аналогично, 0 был увеличен до 1 после предыдущего вызова get_count, то же самое происходит и здесь - он возвращает 1 и увеличивает значение до 2.

Это помогает или это на самом деле более запутанно?

0 голосов
/ 19 февраля 2017

PHP имеет хорошо известное ключевое слово static, которое широко используется в объектно-ориентированном PHP для определения статических методов и свойств, но следует помнить, что static может также использоваться внутри функций для определения статических переменных.

Что такое «статическая переменная»?

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

function countSheep($num) {
 static $counter = 0;
 $counter += $num;
 echo "$counter sheep jumped over fence";
}

countSheep(1);
countSheep(2);
countSheep(3);

Результат:

1 sheep jumped over fence
3 sheep jumped over fence
6 sheep jumped over fence

Если бы мы определили $counter без static, то каждый раз, когда отображаемое значение будет совпадать с параметром $num, переданным функции. Использование static позволяет построить этот простой счетчик без дополнительных обходных путей.

Примеры использования статических переменных

  1. Для сохранения значений между последовательными вызовами функции.
  2. Для сохранения значений между рекурсивными вызовами, когда нет возможности (или нет цель) передать их как params.
  3. Для кэширования значения, которое обычно лучше получить один раз. За пример, результат чтения неизменяемого файла на сервере.

Tricks

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

Статическая переменная может быть определена только как скаляр или скаляр выражение (начиная с PHP 5.6). Присвоение ему других значений неизбежно приводит к провалу хотя бы на момент написания этой статьи. Тем не менее, вы можете сделать это только на следующей строке вашего кода:

function countSheep($num) {
  static $counter = 0;
  $counter += sqrt($num);//imagine we need to take root of our sheep each time
  echo "$counter sheep jumped over fence";
}

Результат:

2 sheep jumped over fence
5 sheep jumped over fence
9 sheep jumped over fence

Статическая функция как бы «разделяется» между методами объектов тот же класс. Это легко понять, просмотрев следующий пример:

class SomeClass {
  public function foo() {
    static $x = 0;
    echo ++$x;
  }
}

$object1 = new SomeClass;
$object2 = new SomeClass;

$object1->foo(); // 1
$object2->foo(); // 2 oops, $object2 uses the same static $x as $object1
$object1->foo(); // 3 now $object1 increments $x
$object2->foo(); // 4 and now his twin brother

Это работает только с объектами того же класса. Если объекты принадлежат к разным классам (даже расширяют друг друга), поведение статических переменных будет таким, как ожидалось.

Является ли статическая переменная единственным способом сохранения значений между вызовами функции?

Другой способ сохранить значения между вызовами функций - использовать замыкания. Замыкания были введены в PHP 5.3. В двух словах они позволяют вам ограничить доступ к некоторому набору переменных в области действия функции другой анонимной функции, которая будет единственным способом доступа к ним. Находящиеся в замыкании переменные могут имитировать (более или менее успешно) такие концепции ООП, как «константы класса» (если они были переданы в замыкании по значению) или «частные свойства» (если переданы по ссылке) в структурном программировании.

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

0 голосов
/ 29 октября 2009

Ну, во-первых, $ count внутри функции и $ count вне функции - это две разные переменные. Это объясняет, почему первый вывод выводит 5.

Теперь для static: Static означает, что ваша локальная переменная создается только один раз, когда функция выполняется в первый раз. Каждое выполнение функции впоследствии использует одну и ту же переменную, поэтому последние значения переменной в последнем выполнении функции все еще там.

Итак, когда вы впервые вызываете get_count (), переменная устанавливается в 0, а затем возвращается. После возврата переменная увеличивается.

При повторном вызове функции переменная по-прежнему равна 1. Это значение возвращается, а затем увеличивается до 2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...