Почему рефконт 2, а не 1? - PullRequest
       24

Почему рефконт 2, а не 1?

8 голосов
/ 19 ноября 2010
  $var = 1;
  debug_zval_dump($var);

Вывод:

long(1) refcount(2)


  $var = 1;
  $var_dup = &$var;
  debug_zval_dump($var);exit;

Вывод:

long(1) refcount(1)

ОБНОВЛЕНИЕ

Очень разочарован ответом ...

Ответы [ 5 ]

28 голосов
/ 19 ноября 2010

void debug_zval_dump (смешанный $ переменная );


код :

$var = 1;              # $var's Refcount = 1
debug_zval_dump($var); # $var is passed by refrence intarlly.

выход

long(1) refcount(2)

Объяснение : Поскольку $ var refcount равен 1, PHP оптимизирует это и обрабатывает память напрямую, а не делает копию, потому что нет никакой возможности засорять любые другие ссылки. PHP внутренне передает $ var по ссылке, так что он может редактировать память напрямую, если это необходимо. Вторая ссылка создается при фактическом вызове debug_zval_dump ().

Ссылка на 2 здесь совершенно неочевидна. Так что же происходит?

Когда переменная имеет единственную ссылку (как $ var, прежде чем она использовалась в качестве аргумента для debug_zval_dump ()), движок PHP оптимизирует способ, которым она передается функции. Внутренне PHP обрабатывает $ var как ссылку (в том смысле, что для области действия этой функции увеличивается значение refcount), с оговоркой, что, если переданная ссылка оказывается записанной, копия создается, но только в момент написания , Это называется «копировать при записи».

Итак, если бы debug_zval_dump () записал свой единственный параметр (а это не так), то копия будет сделана. До тех пор параметр остается ссылкой, в результате чего значение refcount увеличивается до 2 для объема вызова функции.


Код

$var = 1;              # $var's Refcount = 1
$var_dup = &$var;      # $var's Refcount = 2
debug_zval_dump($var); # A copy is passed as $var's refcount is 2.

выход

long(1) refcount(1)

Объяснение : На этот раз копия $ var создается при вызове функции. Это связано с тем, что на $ var ссылаются дважды, и PHP не хочет загрязнять какие-либо другие ссылки, поэтому он создает копию $ var для самостоятельной работы. Так как теперь есть отдельный фрагмент памяти, который используется только для объема вызова функции, он имеет только одну ссылку - это self. Таким образом, для области действия функции счетчик копии равен 1 (он сам).

7 голосов
/ 22 апреля 2011

Я думаю, что документация для этого метода объясняет это в разделе «Осторожно, количество ссылок»:

debug_zval_dump

2 голосов
/ 25 апреля 2011

Код :

$var = 1;
debug_zval_dump($var);

Вывод : long(1) refcount(2)

Объяснение : когда переменная имеетОдиночная ссылка, как и $ var, прежде чем она использовалась в качестве аргумента для debug_zval_dump (), движок PHP оптимизирует способ, которым она передается функции.PHP, в основном, делает указатель на переменную и внутренне, PHP обрабатывает $ var как ссылку, и поэтому его подсчет увеличивается для области действия этой функции.

Код :

$var = 1;
$var_dup = &$var;
debug_zval_dump($var);exit;

Вывод : long(1) refcount(1)

Объяснение : Здесь переменная $ var копируется при записи , создавая совершенно новый разделительэкземпляр этого varable и потому что debug_zval_dump имеет дело с совершенно новой копией $ var, а не ссылкой, ее refcount равен 1. Копия уничтожается, когда функция завершена.

Надеюсь, что это прояснится.

1 голос
/ 19 апреля 2011

Счет 2 здесь крайне неочевиден. Особенно учитывая приведенные выше примеры. Так что же происходит?

Когда переменная имеет единственную ссылку (как $ var1 до того, как она использовалась в качестве аргумента для debug_zval_dump ()), движок PHP оптимизирует способ, которым она передается функции. Внутренне, PHP обрабатывает $ var1 как ссылку (в том смысле, что для области действия этой функции увеличивается значение refcount) с оговоркой, что если переданная ссылка оказывается записанной, копия создается, но только в момент написания , Это называется «копировать при записи».

Таким образом, если бы debug_zval_dump () записал свой единственный параметр (а это не так), то копия будет сделана. До тех пор параметр остается ссылкой, в результате чего значение refcount увеличивается до 2 для объема вызова функции.

- Кредиты переходят на руководство php. Прочитайте полное описание, которое поставляется с функцией, и вы должны были даже спросить ее.

--- Редактировать: Woops, я должен прочитать больше комментариев, прежде чем ответить: D В любом случае, это ответ на вопрос, как упоминалось ранее.

1 голос
/ 19 апреля 2011

Я попытаюсь осветить функцию debug_zval_dump() и способ обработки ваших переменных. Не убивай меня, если я ошибаюсь:) ...

  $var = 1;
  debug_zval_dump($var);

Я думаю, что функция отладки считает $var refcount (1) и 1 refcount (2), поскольку 1 - это значение $var.
Если вы посмотрите на это логически, вы на самом деле говорите это.

  1 = 1;
  debug_zval_dump(1);

Вторая часть:

$var = 1;
$var_dup = &$var;
debug_zval_dump($var);exit;

Здесь вы видите, что вы установили $var на $var_dup, но сохранили его значение. Счет возврата $var равен 1, поскольку вы «связали» его с $var_dup.

$var = 2;
$var_dup = &$var; //or $var = &$var_dup; (doesn't matter which one)
$var = 3;
debug_zval_dump($var_dup);exit;

Это дает long(3) refcount(1) ... Почему это рефконт 1? Как вы можете видеть, значение $ var_dup никогда не было присвоено 3, должно быть 2, верно? Нет, не должно, потому что вы держите его в актуальном состоянии с & $ var. Это означает, что когда вы переходите $var = 4 между $var = 3 и debug_zval_dump($var_dup);exit;, значение $ var_dup будет обновляться автоматически, потому что вы связали их, что делает его 1 повторным счетом.

Тогда есть другое происшествие:

$var = 2;
$var_dup = $var;
$var = 4;
debug_zval_dump($var_dup);exit;

Вывод этого: long(2) refcount(2). Как видите, значение $ var_dup является правильным. $ var было 2, значение было передано через $ var_dup, и он придерживался его. Значение по умолчанию равно 2, потому что это число $var = 4; и $var_dup = $var;. Когда мы удаляем $var = 4;, мы получаем это:

$var = 2;
$var_dup = $var;
debug_zval_dump($var_dup);exit;

Вывод этого: long(2) refcount(3). Теперь функция отладки рассчитывает следующее: $var_dup (1), =$var (2) (поскольку $ var_dup был создан из $ var) и $var (= 2;) (3).

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

И снова, если я ошибаюсь, не убивайте меня:) ...
Привет,
Mixxiphoid

Ответственность
Я не знаю, какова цель этой функции. Я на самом деле никогда не слышал об этом до сегодняшнего дня. Поэтому я не несу ответственности за ненадлежащее использование:).

...