Почему пересчет составляет 2 не 1?

$var = 1; debug_zval_dump($var); 

Вывод:

 long(1) refcount(2) $var = 1; $var_dup = &$var; debug_zval_dump($var);exit; 

Вывод :

 long(1) refcount(1) 

ОБНОВИТЬ

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

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


Код :

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

Выход :

 long(1) refcount(2) 

Объяснение : Так как ref $% var равен 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 для того, чтобы она работала. Поскольку теперь есть отдельная часть памяти, которая используется только для области вызова функции, у нее есть только одно refrence, это я. Таким образом, для объема функции пересчет копии равен 1 (это само).

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

debug_zval_dump

Код :

 $var = 1; debug_zval_dump($var); 

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

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

Код :

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

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

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

Надеюсь, что это очистит.

Я попытаюсь дать немного света функции 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. Это означает, что когда вы debug_zval_dump($var_dup);exit; $var = 4 между $var = 3 и debug_zval_dump($var_dup);exit; значение $ var_dup будет обновляться автоматически, потому что вы связали их, сделав его 1 refcount.

Тогда есть и другое событие:

 $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

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

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

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

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

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

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