[PHP] даже не знаю, как описать проблему...

kruzer25

В общем, есть два класса, по объекту от каждого из них. В первом классе есть переменная $arr, объект второго класса вызывает метод объекта первого, который возвращает ему массив $arr, после чего объект второго класса что-то с этим массивом делает. В результате этого почему-то исходный $arr первого объекта тоже меняется! Воспроизвести такой баг на маленьком количестве кода не получилось...
1) В чём может быть проблема?
2) Как вообще можно этот баг локализовать? Если ошибка в моём коде - тогда можно было бы просто сделать $arr типом private, запись в него осуществлять через __set и всю эту запись выводить в лог, но $obj->arr['aaa']='bbb', почему-то, __set не вызывает...

kruzer25

В общем, уже абсолютно точно ясно, что почему-то возвращается reference на массив, которая потом не разыменовывается (баг в php?) - приходится руками всё поэлементно копировать.
А в php вообще нет никакй возможности нормально разыменовать reference? Только самому и руками?

valodyr

В пятом clone вроде бы работает для массивов.
В четвертом можно сделать, например, array_slice.

valodyr

И, кстати, что лежит в массивах? Не объекты случайно?
И какая версия PHP?

sbs-66

В PHP, если мы создали ссылку на переменную, то оба имени переменных становятся ссылками. Поэтому если ты обращался к элементу массива как к ссылке (или этот элемент объект - они всегда ссылки то этот элемент сам стал ссылкой, и изменение этого элемента в копии массива приводит к изменению элемента в оригинале.
Подробнее - тут

kruzer25

PHP5.2, элементы массива - такие же массивы и строки...
За clone спасибо!

kruzer25

В том-то и проблема, что нигде специально эту ссылку я не указывал. Функция первого объекта возвращает второму внутренний массив первого объекта, а во втором оюъекте потом для этого возвращённого массива вызывается что-то типа foreach($arr as &$val) {...} - но ведь функция первого объекта должна была вернуть новый массив, чтобы внутренние данные объекта не портились от того, что кто-то будет делать с возвращённым значением (там стоит return $arr, а не return &$arr).
Кроме того, воспроизвести этот баг на малом количестве кода мне так и не получилось...
Оставить комментарий
Имя или ник:
Комментарий: