Unset variable в php

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

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

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

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

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

Ответ 1

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

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(), символ $bar связан с этим zval, его счетчик ссылок увеличивается до 2 и устанавливается флаг ссылки.
  • Когда вызывается unset, у zval счетчик ссылок уменьшается до 1, флаг ссылки, вероятно, очищается, а символ $bar удаляется.

См. основы ссылок на ссылки.

Ответ 2

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

Ответ 3

отключенных (самостоятельно:: $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:)

help any?

Ответ 4

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

unset($some_static_var_or_property_holding_a_big_object);

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

$some_static_var_or_property_holding_a_big_object = null;

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

Ответ 5

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

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

Итак, что это означает, если вы unset статическая переменная, вы на самом деле unset ting, что копируете, поэтому, когда функция вызывается снова, она "получает" новую копию.