Оказывается, если мы ссылаемся на элемент массива, то php выносит этот объект отдельно от массива, а в массиве ставит ссылку на него, также как и в текущем объекте, например данный код будет работать не так, как планировалось изначально PHP: <?php $a = array('qw', array('as', 'as')); $b = &$a[1]; $c = $a; var_dump($a); echo '<br>'; unset($c[1][1]); var_dump($a); Посмотрите, интересный нюанс, сам очень долго искал ошибку (конечно в другом коде, это лишь демонстрация), теперь вот проверяю все, боюсь как бы в других местах подобная хрень не вылезла
Вот что нашел еще к теме Баг решено не исправлять, а задокументировать http://bugs.php.net/bug.php?id=20993 Глупость, такой маразм, подобные вещи нужно считать тем - чем они являются, это баг, он нарушает работу логически верной программы
для тех кому влом проверять php 5.3.3: PHP: <?php $a = array('qw', array('as', 'as')); $b = &$a[1]; $c = $a; var_dump($a); echo '<br>'; unset($c[1][1]); var_dump($a); без ссылки PHP: <?php $a = array('qw', array('as', 'as')); //$b = &$a[1]; $c = $a; var_dump($a); echo '<br>'; unset($c[1][1]); var_dump($a); karlozzz и в чём отсутствие логики расскажи?
да, согласен, фигня выходит.... Но впринципе как связанность массивов это фича, но она какая то дибильная...
у меня со второй и без второй строки результаты отличаются. кто-то хочет сказать, что так и должно быть?
Если мне надо будет сделать так, я сам сделаю, а я хочу именно ссылку на элемент массива, а интерпретатор какую то ху*** делает
Вполне адекватное поведение Сначала создается статичная переменная $a типа массив При обращении к ней как к ссылке вся переменная $a становится ссылкой на массив, $b - ссылка на часть массива (массив - кусок памяти, ссылки на него - переменная с адресом этой памяти) $c = $a - создается еще одна ссылка на этот же массив unset($c[1][1]); удаляется часть массива по ссылке по сути, просто неявное преобразование типов
С чего бы вдруг? Глупость, $c копия $a Дело то в том, что когда мы пытаемся сослаться на массив $b = &$a[1]; Тогда происходит примерно такое (что по логике происходить не должно) $tmp = $a[1]; $a[1] = &$tmp; $b = &$tmp; Поэтому когда мы копируем массив $c = $a Массив копируется нормально, но подмассива $a[1] не существует, в нем хранится ссылка на $tmp (некую область памяти), что я считаю не верными действиями интерпретатора, конечно самый простой вариант не исправлять баг, а задокументировать его...
с того, что изначально была переменная, отдельная, статичная, и тут понадобилось сделать ссылку на часть этой переменной. соотв. массив разворачивается как отдельная сущность в памяти, $a указывает на начало сегмента памяти, $b на другой участок этой памяти Если бы в PHP массивы сразу бы представлялись ссылками на сегмент памяти (как в C), я думаю таких недоразумений не было бы) глупость не читать мануалы при $c = $a - создается ссылка на $a до тех пор пока над $c не производили никаких действий (php>5.0), т.е. значение из $a скопируется напр только после $c = $c + 1; (зы. объекты всегда передаются по ссылке) но поскольку $a = ссылка на массив, то $c автоматически тоже становится ссылкой на массив простой пример PHP: <?php echo 'START: ' . memory_get_usage() . PHP_EOL; $a = array('a', 'xcv', 'ertc', 'dttre', 'cxc', 'r6y', '234'); echo 'CREATED $a: ' . memory_get_usage() . PHP_EOL; // array size - 1 488b $b = $a; echo 'CREATED $b: ' . memory_get_usage() . PHP_EOL; // link size - 96b $b[] = 'x'; echo 'MODIFIED $b: ' . memory_get_usage() . PHP_EOL; // new array size - 1 024b + 96b = 1 120b
ничего подобного, если сделаете var_dump($b) в конце, то увидите, что она указывает на основной массив и соотв. тоже изменилась, копирования не происходит
Да, в $c что то типа ссылки на $a , но при изменении $c объект копируется, это без вопросов, но это не еще одна ссылка на $a, фактически это копия $a А как по твоему хранятся СТАТИЧНЫЕ массивы?))) $a не становится ссылкой на массив, она так и остается массивом (если отталкиваться от уровня php, а не ниже), просто часть $a, а именно $a[1] фактически становится отдельным объектом на который ссылается $b Тут не понял, с чего ты взял что она указывает на основной массив, ты посмотри var_dump($a), в нем $a[1] по ссылке хранится
Смотрим 1 PHP: <?php $a = array('qw', array('as', 'as')); var_dump($a); echo '<br>'; $b = &$a[1]; var_dump($a); echo '<br>'; $c = $a; var_dump($a); echo '<br>'; unset($c[1][1]); var_dump($a); echo '<br>'; var_dump($b); echo '<br>'; ?>
Смотрим 2 PHP: <?php $a = array('qw', array('as', 'as')); var_dump($a); echo '<br>'; $tmp = $a[1]; $a[1] = &$tmp; $b = &$tmp; var_dump($a); echo '<br>'; $c = $a; var_dump($a); echo '<br>'; unset($c[1][1]); var_dump($a); echo '<br>'; var_dump($b); echo '<br>'; ?>
alBoo Да не, я наверное херово объяснил, но баг интересный, столько геммороя может в самый неподходящий момент доставить, устранять его я считаю надо, посмотрим что в пхп6 будет, кто нить знает когда выход?
igordata Да, скорей всего, поэтому и не устраняют, просто наверное сейчас нет возможности сделать ссылку на часть массива, мб из-за того что адрес динамический или еще какой либо нюанс, и это как выход из положения, но слышал, что в пхп6 архитектура претерпит ряд глобальных изменений, вот хочу услышать, мб у кого информация есть
Ссылки в пхп - это записи указывающие на одну и ту же структуру переменной. Именно по-этому это не совсем то, что ссылки в Си. Т.е. есть стуктура в памяти хранящая данные, есть таблица - имя/указатель на эту структуру. Ожидать, что можно будет не только указатель сделать, но еще и на какую-то субстуктуру указать - странно. Так что от понимания того, как работают ссылки становится все более-менее логично. Ссылки вообще вещь не прозрачная, а в связи с тем, что есть ссылки в пхп - рождает кучу непонимания. Отсюда вывод - не изучив подробно как работают ссылки внутри ПХП - использовать их нельзя.
MiksIr В идеале работая на языке высокого уровня, нужно знать только то что написано в документации и относится именно к высокому уровню, а уж способы хранения структур данных в памяти и подобные нюансы могут без предупреждения разработчиков меняться от версии к версии в интерпретаторе
Это ваши домыслы о том, что нужно, а что не нужно знать. Они особо никого не интересуют. Те, кто использует возможности языка серьезно - читают документацию. А там, если не ошибаюсь, сказано, что ссылки внутри массива - опасны.