Задать вопрос
@MaxPyane

Куда утрачивается ссылка на параметр в методе?

Имею не мало опыта работы с PHP, но в этот раз напоролся на не очевидный для меня подводный камень с ссылками который никогда до этого не встречал, может баг, а может я туплю. В общем простой метод, который играет роль заполнителя внешнего хранилища $storage (простая переменная-объект). Проблема возникает когда я внутри метода обращаюсь к сторонней библиотеке (ReflectionDocBlock), она мне парсит док коммент откуда я в свою очередь выдергиваю некоторые ха-ки и добавляю в $storage. Иногда она не может спарсить (например плохо сделанный док коммент), и именно в этот момент происходят какие-то аномалии хотя ни ошибок, ни исключений она не кидает.

private function parseClassAttrsIn(object &$storage, object $source)
{
    $storage->name = 'test';
    // Смотрим что внутри
    var_dump($storage); // object(classStorage)#2513 (1) { ["name"]=> string(4) "test" }

    // Вызываем метод который просто обращается к инстансу ReflectionDocBlock,
    // ничего в нем магического нет
    $docBlock = $this->reflectionDocBlock($source->getDocComment());

    // Опять смотрим что внутри
    var_dump($storage); // string(20) "object(classStorage)"
}

Что здесь произошло o_O? Единственное что осталось от моего $storage'a это описательная стринга, мол здесь был объект classStorage...
Я попробовал работать без ссылки и возвращать $storage, проблема уходит, но это не вариант.
private function parseAttrsIn(object $source, object $storage)
{
    $storage->name = 'test';
    // [...]
    return $storage;
}

Этот $storage удобно передавать ссылкой другим методам и заполнять его ха-ками. Я знаю что PHP очень умный и оптимизированный внутри, и параметры, даже если там обычная переменная, все равно передается по ссылке, и при обращении к нему внутри функции/метода мы все так же работаем с ссылкой, но как только мы задумали его изменить, то он копируется и превращается в локальную переменную. Без амперсанда я теряю $storage, т.к внутри метода изменяю его динамически объявляя свойства. Как я понимаю, амперсандом я говорю PHP в лоб не копировать, а продолжать работать через ссылку.
Понять что за аномалия там происходит я не могу, достаточно перестать обращаться к внешней библиотеке (закомментировать) и ссылки не ломаются. У кого какие идеи?
  • Вопрос задан
  • 131 просмотр
Подписаться 2 Сложный 2 комментария
Пригласить эксперта
Ответы на вопрос 1
SilenceOfWinter
@SilenceOfWinter Куратор тега PHP
та еще зажигалка...
передавать объекты по ссылке как минимум не имеет смысла т.к. объект переданный в метом все равно указывает на тот же объект и отзязать его можно только через клонирование.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы