переменная сброса в php

Я просто читал о переменной сброса через php руководство.

В php руководстве говорится, что "сброс () уничтожает указанные переменные"

Это определение кажется прекрасным, пока я не столкнулся со статической переменной... "Если статическая переменная сброшена () в функции, сбросьте (), уничтожает переменную только в контексте остальной части функции. Следующие вызовы восстановят предыдущее значение переменной".

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

Кто-либо еще думает, что лучшее определение было бы "сброшено (), делает переменную из текущей области"? Я имею в виду, вместо того, чтобы указать на время жизни, лучше использовать объем слова здесь?

11
задан Austin Hyde 7 July 2010 в 13:40
поделиться

4 ответа

Рассмотрим функцию:

function foo() {
    static $bar;
    $bar++;
    unset($bar);
}
foo(); //static $bar is 1
foo(); //static $bar is 2

Функция компилируется в:

function name:  foo
number of ops:  11
compiled vars:  !0 = $bar
line     # *  op                           fetch          ext  return  operands
---------------------------------------------------------------------------------
   2     0  >   EXT_NOP                                                  
   4     1      EXT_STMT                                                 
         2      FETCH_W                      static              $0      'bar'
         3      ASSIGN_REF                                               !0, $0
   5     4      EXT_STMT                                                 
         5      POST_INC                                         ~1      !0
         6      FREE                                                     ~1
   6     7      EXT_STMT                                                 
         8      UNSET_VAR                                                !0
   7     9      EXT_STMT                                                 
        10    > RETURN                                                   null

Фактически переменная существует вне каждого вызова функции foo () и при каждом вызове он извлекается, и ссылка на него назначается $ bar . Фактически, это очень похоже на это:

function foo() {
    global $bar;
    $bar++;
    unset($bar);
}

Когда вы вызываете unset () , вы уничтожаете только созданную ссылку, а не базовое значение.

Я не подтверждал, но я предполагаю, что происходит следующее:

  • Базовое представление переменной (zval) сохраняется так, что ее счетчик ссылок равен 1.
  • Когда Вызывается foo () , с этим zval связан символ $ bar , его счетчик ссылок увеличивается до 2 и устанавливается флаг ссылки.
  • Когда вызывается unset , счетчик ссылок zval уменьшается до 1, флаг ссылки, вероятно, сбрасывается и символ $ bar удаляется.

См. основы подсчета ссылок .

15
ответ дан 3 December 2019 в 03:03
поделиться

Внутри функции имена переменных, ссылающиеся на статические переменные, являются просто ссылками. По сути, unset уничтожает ссылку.

9
ответ дан 3 December 2019 в 03:03
поделиться

отключено (self :: $ somethingstatic); вызовет фатальную ошибку, потому что переменная статична (всегда присутствует, не может быть сброшена).

документация относится конкретно к статическим переменным, определенным внутри функции, примите во внимание:

function t($stage)
{
  static $shell = 23;
  switch($stage) {
    case 1:
      $shell++;
      break;
    case 2:
      unset($shell);
      break;
    case 3:
      $shell--;
    break;
  }
  echo $shell;
}

поскольку $ shell - это статическая переменная, она всегда присутствует (статическая), поэтому в любой другой раз, когда вы упоминаете $ shell, это просто ссылка - когда вы отключите его, вы отключите ссылку (подумайте об отключении символической ссылки) - статическая переменная, тем не менее, все еще существует (что означает статика).

таким образом, если вы вызовете вышеуказанную функцию, t (1) будет эхо 24, t (2) не будет эхом ничего, а t (3) (справедливо) будет эхо 23 :)

кому-нибудь поможет?

4
ответ дан 3 December 2019 в 03:03
поделиться

Что ж, unset () очищает память, связанную с именем переменной.

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

Итак, это означает, что если вы отключите статическую переменную, вы фактически отключите эту копию, поэтому, когда функция вызывается снова, она «получает» свежий экземпляр.

0
ответ дан 3 December 2019 в 03:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: