LINUX.ORG.RU
ФорумTalks

Ссылки в пхп, неадекватное поведение

 


1

3

В связи с темой PHP 8.4 — большое обновление языка, напомнившей мне про пхп, решил его кое-где применить и в ходе планирования наткнулся на такую штуку.

Примеры:

<?php
  $a = array('a' => 1);
//  $X = array(&$a['a']); $X = 1;
  $b = $a;
  $a['a'] = 2;
  var_dump($b);
<?php
  $a = array('a' => 1);
  $X = array(&$a['a']);// $X = 1;
  $b = $a;
  $a['a'] = 2;
  var_dump($b);
<?php
  $a = array('a' => 1);
  $X = array(&$a['a']); $X = 1;
  $b = $a;
  $a['a'] = 2;
  var_dump($b);
<?php
  $a = array('a' => 1);
  $X = array(&$a['a']);
  $b = $a;
  $a['a'] = 2;
        $X = 1;
  var_dump($b);
<?php
  $a = array('a' => 1);
  $X = array(&$a['a']);
  $b = $a;
        $X = 1;
  $a['a'] = 2;
  var_dump($b);
в зависимости от операций над совершенно посторонней переменной будет меняться содержимое $b. Почему оно так себя ведёт - понятно (кому непонятно, попробуйте сами без подсказок догадаться, возможно будет занимательно; а те, кто считает себя профессиональными пхпшниками, попробуйте не выполняя скрипты догадаться каким будет их результат, тоже интересно). Пятый вариант кстати оказался неожиданностью, но и ему нашлось ещё одно объяснение.

Но, тем не менее, я всё же немножко удивился, что они эту штуку не попытались как-то хотя бы спрятать с глаз, всё-таки некрасиво получается.

Впрочем, это, как и остальные его мелкие некрасивости, никак не влияет на тот факт, что пхп всё равно лучший вариант для «накодить несложное по-быстрому».

★★★★★

Последнее исправление: firkax (всего исправлений: 4)

Пятница была вчера, у тебя в примере первом ничего не меняется, зачем еще 10 штук я не разбирался. Ссылки работают ближе к var-аргументу в паскале, чем к указателю в С.

Вообще проще их избегать используя классы, они передаются без копирования как массивы, а «по указателю».

MOPKOBKA ★★★★★
()
Последнее исправление: MOPKOBKA (всего исправлений: 4)
Ответ на: комментарий от MOPKOBKA

Что значит «в примере ничего не меняется»? Надо разные примеры друг с другом сравнивать.

Как работают ссылки я знаю, а ты кажется нет. Они с аргументами вообще никак не связаны.

firkax ★★★★★
() автор топика
Ответ на: комментарий от firkax

Если бы ты знал, то треда бы не было. 10 примеров сравнивать между собой то еще удовольствие (визуально что бы понять чем они отличаются хотя бы), уверен отпишется пол лора, только скопирует их в блокнот себе.

Примерами можно подловить тех кто не пишет на PHP, но именно логикой копирования массива, во всех языках это обычно не копии а ссылки.

MOPKOBKA ★★★★★
()
Последнее исправление: MOPKOBKA (всего исправлений: 2)
Ответ на: комментарий от MOPKOBKA

Если бы ты знал, то треда бы не было.

Что ты несёшь? Дочти до конца тему перед ответом.

Примерами можно подловить

Я никого не собирался подлавивать. Повторю, дочитай до конца, потом пиши. Если неинтересно - просто иди мимо (тема толксах, если ты не заметил, а значит она носит развлекательный характер).

firkax ★★★★★
() автор топика

Это описано в документации. Почему – лично я недопетрил. Лень. Но это странность, да.

rechnick ★★★
()
Ответ на: комментарий от rechnick

Хм, и правда описано, но оно от этого менее странным не становится. И кстати поведение пятого примера там не описано.

firkax ★★★★★
() автор топика
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от firkax

менее странным не становится

А можно как-то в двух словах сказать что тебе кажется странным. Неспособность сформулировать претензию и выкатывание простыни из примеров как бы говорит что ТЫ всё таки нишиша не понимаешь в ссылках.

PS: а ещё какие-то тупые примеры используешь. Зачем писать $X=1 если можно $X=42 и тогда будет понятно где было реальное изменение, а где «просто совпало».

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 2)
Ответ на: комментарий от firkax

И кстати поведение пятого примера там не описано.

Не вижу смысла описывать все 100500 примеров этой хрени. Фраза из справки 21 года (свежая онлайн сейчас недоступна): «Иными словами, поведение отдельных элементов массива не зависит от типа присвоения этого массива». Если в пятом примере вместо $X = array(&$a[‘a’]); сделать $X = &$a[‘a’]; то на выходе будет &int(2). Что ещё более странно.

Для себя я это объясняю так: если на значение в массиве появляется ссылка, то все переменные на это значение волшебным образом становятся ссылками. Скорей всего абсолютно неграмотно объяснил, но уж как смог.

rechnick ★★★
()
Последнее исправление: rechnick (всего исправлений: 1)

Вы в который раз пытаетесь рассуждать о том в чем вообще дупля не отбиваете, прекращайте. Передача по ссылке и по значению это функционал языка, а не «некрасивость».

Obezyan
()
Ответ на: комментарий от no-such-file

Ну переставь на 42. Странность в том что от присваивания переменной $X чего угодно зависит результат присваивания $b=$a;

Повторюсь, я прекрасно понимаю почему технически так получается, но это технические подробности, а с «потребительской» точки зрения это поведение странное и провоцирующее баги.

Неспособность сформулировать претензию и выкатывание простыни из примеров как

Ещё один (первый МОРКОВКА) не понял сути темы. Тема в толках, она для занимательного чтения и развлечения. Если оказалась не в твоём вкусе - ну извини, не угодил, а кому-то будет интересно.

firkax ★★★★★
() автор топика
Ответ на: комментарий от Obezyan

Ты в который раз опозорился, не осилив прочитать тему перед тем как отвечать и ляпнув в итоге что-то неуместное.

firkax ★★★★★
() автор топика
Ответ на: комментарий от rechnick

Что ещё более странно.

Да не, не странно.

если на значение в массиве появляется ссылка, то все переменные на это значение волшебным образом становятся ссылками.

*** спойлер ***

Всё проще: пхп-ссылка это аналог хардлинка в файловой системе, у неё нет «оригинала» и «ссылки», есть только две ссылки на общее значение. А когда ты копируешь массив, то он, поскольку не отличает оригинал от сделанной ссылки, копирует это поле как ссылку на то же самое значение. Если же перед копированием уже сделанную ссылку затереть ($X=1), то поле получает назад numrefs=1 и обрабатывается как нормальная переменная.

Продолжая аналогию с файловой системой, это как если бы команда cp проверяла наличие хардлинка и, если он есть, делала не копию а ln.

Что касается пятого примера, в котором ссылка затирается уже после $b=$a и, казалось бы, элемент массива к тому времени уже скопирован в виде ссылки, а по факту оказывается нет - массивы выходят не связанные. Объяснение такое: $b=$a массив не копирует, а только запоминает что у обеих переменных одинаковое значение (по сути дедупликация, ананог в файловой системе - reflink, в старых фс такое не поддерживается). Реально клонирует он её только когда в одну из виртуальных копий делается запись (тут уж никак не получится хранить вместе). Если б не ссылки - это поведение нигде бы наружу не протекало, но вместе со ссылками оно создаёт ещё большую странность.

firkax ★★★★★
() автор топика
Ответ на: комментарий от firkax

Для меня это что-то вроде замыканий в js. Когда объект не утилизируется после выполнения функции. Просто такой эффект. Типа недоперемудрили, но подняли шум об уникальной фиче.

rechnick ★★★
()
Ответ на: комментарий от firkax

Ты в который раз опозорился, не осилив прочитать тему перед тем как отвечать и ляпнув в итоге что-то неуместное.

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

Obezyan
()
Ответ на: комментарий от firkax

не осилив прочитать тему

А ее вообще никто не осилил прочитать, кроме речника. Мне вот лень.

goingUp ★★★★★
()

А вот, удалось всё «странности» в один пример объединить:

<?php
  $a = array('a'=>1,'b'=>4);
  $X = array(&$a['a']);
  $b = $a;
//  $Y = array(&$a['b']);
  $X = 1;
  $a['a'] = 2;
  var_dump($b);
Значение поля 'a' в выводе будет разным в зависимости от того, закомментирована строка или нет.

firkax ★★★★★
() автор топика
Ответ на: комментарий от firkax

В вот, что говорит нам мега умный искусственный интеллект:

Uncommenting the $Y line does not change the behavior of var_dump($b) because $b remains unaffected by the addition of $Y.

seiken ★★★★★
()
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)