unset переменная в php - PullRequest
       5

unset переменная в php

10 голосов
/ 07 июля 2010

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

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

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

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

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

Ответы [ 5 ]

13 голосов
/ 07 июля 2010

Давайте рассмотрим функцию:

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 удаляется.

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

9 голосов
/ 07 июля 2010

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

3 голосов
/ 07 июля 2010

снята с охраны (само :: $ 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, которая является просто ссылкой, - когда вы ее отменяете, вы отменяете ссылку (например, не связывая символическую ссылку) - статическуюпеременная, тем не менее, все еще существует (это то, что означает static).

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

помочь любому?

1 голос
/ 27 февраля 2014

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

unset($some_static_var_or_property_holding_a_big_object);

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

$some_static_var_or_property_holding_a_big_object = null;

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

0 голосов
/ 07 июля 2010

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

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

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

...