Пример #1 Пример использования debug_zval_dump()
<?php
$var1 = 'Hello World';
$var2 = '';
$var2 =& $var1;
debug_zval_dump(&$var1);
?>
Результат выполнения данного примера:
&string(11) "Hello World" refcount(3)
Замечание:
Предостережение по поводу refcount
Значение refcount, возвращаемое этой функцией,
не очевидно в некоторых случаях. Например, разработчик может
ожидать, что в приведенном выше примере значение refcount будет
2. Третья ссылка была создана в момент
вызова debug_zval_dump().
Это поведение более сложно, когда переменная не передается в функцию
debug_zval_dump() по ссылке. Для иллюстрации рассмотрим
немного измененный вариант приведенного выше примера:
<?php
$var1 = 'Hello World';
$var2 = '';
$var2 =& $var1;
debug_zval_dump($var1); // в этот раз не передается по ссылке
?>
Результат выполнения данного примера:
string(11) "Hello World" refcount(1)
Почему refcount(1)? Потому что создается копия $var1,
когда вызывается функция.
Эта функция становится еще более сбиваювщей с толку, когда
передается переменная со значением refcount, равным 1
(копиерованием/по значению):
<?php
$var1 = 'Hello World';
debug_zval_dump($var1);
?>
Результат выполнения данного примера:
string(11) "Hello World" refcount(2)
Значение refcount, равное 2, в данном случае совсем
непонятно. Особенно учитывая приведенные выше примеры. Так в чем же дело?
Когда переменная имеет единственную ссылку (как было с переменной $var1,
перед тем, как ее передали в качестве аргумента в функцию debug_zval_dump()),
процессор PHP оптимизирует метод, которым она передается в функцию.
Внутренне, PHP рассматривает $var1 как ссылку (таким образом
refcount увеличивается для области видимости
функции), при условии, что если в переданную ссылку
придется производить запись, создается копия, но только в момент
записи. Такое поведение известно как "copy on write."
Таким образом, если debug_zval_dump() приходится писать в свой единственный
параметр (и не делает этого), то будет создана копия. До этого момента
параметр остается ссылкой, приводя к увеличению refcount
до 2 в области видимости вызова функции.