no_alex
Новичок
Элементы массива по ссылке - баг или фича?
Наступил на очень неприятные грабли....
Чтобы долго не расписывать суть, приведу пример простого тестового кода:
В результате выполнения этого кода мы получаем:
Обратите внимание на то, что методы get1() и get2() возвращают копии массивов, а не ссылки на них.
Но, не смотря на это, последующие изменения в "копиях" меняют и "оригинал". Причём, не важно с каким массивом я работаю с исходным или с клоном.
Я вначале подумал что это баг, но порассуждав немного - понял, что это "фича".
На всякий случай проверил эту фичу в PHP6 - работает тоже (по крайней мере, в той версии, что они сейчас предлагают).
Но на мой взгляд это очень "опасная фича". Я, по крайней мере, уже переписал часть своего кода чтобы такие ссылки "наружу" не попадали.
В продолжение этого рассуждения хочу спросить - я читал на многих форумах (в т.ч., по моему, и здесь эта тема поднималась), что в PHP6 хотят очень сильно ограничить использование ссылок. Я проверил множество вариантов работы со ссылками и не увидел особой разницы с PHP5.
Единственное, что они убрали параметр allow_call_time_pass_reference. В результате вот такой код:
выдает
, но все равно правильно отрабатывает (выдаст 2).
Так что же такого существенно изменилось в PHP6 при работе со ссылками? Или только ограничена передача ссылки снаружи в функцию?
Наступил на очень неприятные грабли....

Чтобы долго не расписывать суть, приведу пример простого тестового кода:
PHP:
<?php
class w
{
private $a = array();
private $b = array();
public function init() {
$this->a = array("x" => 1, "y" => 2, "z" => 3);
foreach ($this->a as $k => $v) {
$this->b[$k] =& $this->a[$k];
}
}
public function get1() {
return $this->a;
}
public function get2() {
return $this->b;
}
public function view() {
echo "<pre>";
print_r($this->a);
print_r($this->b);
echo "</pre>";
}
}
$o = new w();
$o->init();
$c1 = $o->get1();
$c1["x"] = 5;
$c2 = $o->get2();
$c2["y"] = 6;
$o->view();
?>
Код:
Array
(
[x] => 5
[y] => 6
[z] => 3
)
Array
(
[x] => 5
[y] => 6
[z] => 3
)
Но, не смотря на это, последующие изменения в "копиях" меняют и "оригинал". Причём, не важно с каким массивом я работаю с исходным или с клоном.
Я вначале подумал что это баг, но порассуждав немного - понял, что это "фича".
На всякий случай проверил эту фичу в PHP6 - работает тоже (по крайней мере, в той версии, что они сейчас предлагают).
Но на мой взгляд это очень "опасная фича". Я, по крайней мере, уже переписал часть своего кода чтобы такие ссылки "наружу" не попадали.
В продолжение этого рассуждения хочу спросить - я читал на многих форумах (в т.ч., по моему, и здесь эта тема поднималась), что в PHP6 хотят очень сильно ограничить использование ссылок. Я проверил множество вариантов работы со ссылками и не увидел особой разницы с PHP5.
Единственное, что они убрали параметр allow_call_time_pass_reference. В результате вот такой код:
PHP:
<?php
function x($a) {
$a = 2;
}
$b = 1;
x(&$b);
echo $b;
?>
Код:
Deprecated: Call-time pass-by-reference has been deprecated; if you would like to pass argument by reference, modify the declaration of x(). in test.php on line 6
Так что же такого существенно изменилось в PHP6 при работе со ссылками? Или только ограничена передача ссылки снаружи в функцию?