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