Подтвердить что ты не робот

Эта переменная относится к самому себе

Я прочитал много статей о том, как построить переменные внутри машины Zend и нашел одну интересную вещь, которую я не могу объяснить:

$int = 100;
xdebug_debug_zval('int'); /// int:(refcount=1,is_ref=0),int 100
$int = &$int;
xdebug_debug_zval('int'); /// int:(refcount=1,is_ref=1),int 100

Как выясняется, мы сами создаем ссылку? Как это возможно?

Очистить информацию от того, что я знаю:

Как правило, is_ref = 1, только когда контейнер ссылается на zval две или более переменных жесткой ссылки.

refcount - количество переменных относится к одному и тому же контейнеру zval, но разница в том, что пересчет для разных работает с is_ref = 0 и is_ref = 1.

Если is_ref = 0 и refcount > 1 при создании жестких ссылок мы получаем новый zval-контейнер, если мы выполняем присвоение значением - новый zval-контейнер не будет создан.

Если is_ref = 1 и refcount > 1 при создании жестких ссылок новый zval не создается, используется старый. если мы не создаем жесткую ссылку, но присваиваем ее значением - это означает, что мы создали новый контейнер zval.

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

4b9b3361

Ответ 1

Ответ довольно прост, как объясняется в комментариях к вашему вопросу. Хотя, я думаю, я понимаю, откуда твоя путаница, так что пусть это сломается.: D

Сначала вы назначаете значение переменной, внутренне PHP сохраняет это в сегменте памяти и увеличивает счетчик переменных, который ссылается на этот адрес. (Ref = 1). Все прямо вперед до этого момента.
Затем вы повторно используете переменную для хранения ссылки (указатель в C-терминалах) на этот адрес памяти. В руководстве по PHP объясняется это как сохранение ссылки на переменную, чтобы упростить работу программистов, не относящихся к C, и именно там (я думаю) возникает ваше замешательство. Нет такой вещи, как ссылка на переменную во внутренних элементах, только данные, с которыми связана переменная. Поскольку вы повторно использовали переменную для хранения этой ссылки, счетчик ссылок не увеличивается: по-прежнему существует только одна переменная, указывающая на этот сегмент памяти. Тем не менее, это уже не обычная PHP-переменная, а ссылка (указатель) на данные.

Изменить, добавлено:
Другой способ добиться того же результата - использовать две переменные, а затем unset первую. Пример кода:

$a = 100; // refcount += 1
xdebug_debug_zval ('a'); // refcount=1,is_ref=0 -> zval {value=100,type=int (addr=0x78765asd)}

$b =& $a; // refcount += 1
xdebug_debug_zval ('a') // refcount=2,is_ref=0 -> zval {value=100,type=int (addr=0x78765asd)}
xdebug_debug_zval ('b') // refcount=2,is_ref=1 -> zval {value=100,type=int (addr=0x78765asd)}

unset ($a); // refcount -= 1
xdebug_debug_zval ('b') // refcount=1,is_ref=1 -> zval {value=100,type=int (addr=0x78765asd)}

Использование только одной переменной объединяет две операции в одну, не уничтожая данные. Таким образом: 1 переменная (refcount = 1), которая является ссылкой (is_ref = 1) для самих данных.

Как мы и пытались объяснить вам, путаница проистекает из того, что предпосылка исходного вопроса ошибочна: вы не ссылаетесь на переменную в этих примерах, вы ссылаетесь на область памяти, которая содержит данные, первоначально связанные с указанной переменной. Таким образом, вы переписываете одну (оригинальную) "жесткую ссылку", а другую. Единственное отличие состоит в том, что последний помечен как таковой, по внутренним причинам PHP. (Ссылки не копируются при записи, в случае refcounts > 1.)