Подтвердить что ты не робот

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

$count = 5;
function get_count()
{
    static $count = 0;
    return $count++;
}
echo $count;
++$count;
echo get_count();
echo get_count();

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

4b9b3361

Ответ 1

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

Ответ 2

$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)

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

Ответ 3

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

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

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

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

Ответ 4

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

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

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

Помогает ли это или является ли это более запутанным?

Ответ 5

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

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

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

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

Ответ 6

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 позволяет построить этот простой счетчик без дополнительного обхода.

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

  • Сохранение значений между последовательными вызовами функции.
  • Сохранять значения между рекурсивными вызовами, когда нет способа (или нет цель) передать их в качестве параметров.
  • Кэш-значение, которое обычно лучше извлекать один раз. Для пример, результат чтения неизменяемого файла на сервере.

Трюки

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

Статическая переменная может быть определена только как скаляр или как скаляр   выражение (с 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

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

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

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

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