Intereting Posts
phpExcel записывает длинное число в ячейку Предупреждение: imagejpeg () : gd-jpeg: библиотека JPEG сообщает о неустранимой ошибке Скрыть URL для загрузки Статические методы в PHP: зачем? Как предотвратить SQL-инъекцию с динамическими именами таблиц? Есть ли бесплатный open source PHP translit lib? Новая установка Symfony 3: не удалось открыть входной файл: приложение / консоль в установке композитора magento ограничение количества возвращенных предметов в вызове коллекции продуктов Безопасно ли использовать mysql_affected_rows Сохранять состояние XHR при обновлении браузера отправлять электронную почту с вложением в php без сохранения файла на веб-сервере Получение массива изображений на HTML-странице с помощью PHP Степень «°» не отображается в функции php json_encode, как отобразить это? Как создать динамическую ассоциацию сущностей с Doctrine2 в Symfony2 php datetime-> diff вычисляет неправильное количество часов (3 слишком много)

Передаются ли объекты PHP5 по ссылке?

Кажется, я не могу получить какую-либо последовательную информацию об этом. Кажется, что разные источники говорят о разных вещах, и сам почтенный php.net (явно) не указывает это явно, хотя, признаюсь, я только быстро посмотрел.

В случаях, когда я передаю «тяжелые» объекты, мне нужно пройти по ссылке, но я не хочу продолжать печатать:

function foo(TypeName& $obj) 

если я могу уйти просто

 function foo(TypeName $obj) 

Так что же говорит стандарт?

Объекты передаются (и назначаются) по ссылке. Нет необходимости использовать адрес оператора.

Предоставлено, что я набрал, является упрощением, но подойдет вашим целям. В документации указано:

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

Ссылка PHP – это псевдоним, который позволяет двум различным переменным писать одно значение. Начиная с PHP5, объектная переменная больше не содержит объект как значение. Он содержит только идентификатор объекта, который позволяет объектным аксессуарам находить фактический объект. Когда объект отправляется аргументом, возвращенным или назначенным другой переменной, разные переменные не являются псевдонимами: они содержат копию идентификатора, которая указывает на тот же объект.

Для более подробного объяснения (объясняет упрощение, а также идентификаторы) проверьте этот ответ .

Из руководства по PHP :

Вы можете передать переменную по ссылке на функцию, чтобы функция могла изменять переменную. Синтаксис выглядит следующим образом:

 <?php function foo(&$var) { $var++; } $a=5; foo($a); // $a is 6 here ?> 

Примечание. В вызове функции нет ссылочного знака – только для определения функций. Определений функций достаточно, чтобы правильно передать аргумент по ссылке. Начиная с PHP 5.3.0, вы получите предупреждение о том, что «call-time-pass-by-reference» устарело, когда вы используете & in foo (& $ a) ;.

И из What's New в PHP5 :

В PHP 5 инфраструктура объектной модели была переписана для работы с дескрипторами объектов. Если вы явно не клонируете объект с помощью ключевого слова clone, вы никогда не создадите его за дублированными объектами. В PHP 5 нет необходимости передавать объекты по ссылке или присваивать их по ссылке

Таким образом, единственный раз, когда вам нужно использовать синтаксис function foo(&$var) указать, что $ var может не быть экземпляром класса.

Кажется, что это немного более точно, значение объекта передается по значению, но значение самого объекта является указателем. Это отличается от простого прохождения ссылки.

На http://www.php.net/manual/en/language.oop5.references.php приведенный пример хорош. В первом наборе $ a = NULL; не влияет на $ b, так как $ a был всего лишь указателем. Во втором наборе $ c = NULL; заставляет $ d быть NULL, так как $ d является ссылкой на $ c.

 <?php class A { public $foo = 1; } $a = new A; $b = $a; $a->foo = 2; $a = NULL; echo $b->foo."\n"; // 2 $c = new A; $d = &$c; $c->foo = 2; $c = NULL; echo $d->foo."\n"; // Notice: Trying to get property of non-object... ?> 

Начиная с PHP 5, все объекты передаются и присваиваются по ссылке.

В PHP 4 вам все равно нужно указать, где вы хотите передать объекты по ссылке, явно используя оператор & .

Короткий ответ – да . Из объектов и ссылок :

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

Ссылка PHP – это псевдоним, который позволяет двум различным переменным писать одно значение. Начиная с PHP5, объектная переменная больше не содержит объект как значение. Он содержит только идентификатор объекта, который позволяет объектным аксессуарам находить фактический объект. Когда объект отправляется аргументом, возвращенным или назначенным другой переменной, разные переменные не являются псевдонимами: они содержат копию идентификатора, которая указывает на тот же объект.

Важно то, что в случае, когда вас беспокоит, вы никогда не будете делать копию объекта, если вы явно не используете ключевое слово clone в вызове функции. Является ли это псевдонимом или идентификатором, это не изменяет этот факт.

Да, начиная с PHP5, объекты передаются по ссылке. Нет необходимости делать это явно.

http://www.php.net/manual/en/migration5.oop.php

В PHP 5 есть новая объектная модель. Обработка PHP объектов полностью переписана, что обеспечивает лучшую производительность и дополнительные функции. В предыдущих версиях PHP объекты обрабатывались как примитивные типы (например, целые числа и строки). Недостатком этого метода было то, что семантически весь объект был скопирован при назначении переменной или передан как параметр для метода. В новом подходе объекты ссылаются на дескриптор, а не по значению (можно рассматривать дескриптор как идентификатор объекта).

Просто пример, в котором полезно использовать «объекты» по ссылке:

 class RefTest1 { public $foo; public function __construct(RefTest2 &$ref = null) { $this->foo =& $ref; } } class RefTest2 { public $foo; public function __construct(RefTest1 &$ref = null) { $this->foo =& $ref; } } class RefTest3 { public $foo; public function __construct(RefTest2 &$ref = null) { $this->foo =& $ref; } } class DoCrossRef { public $refTest1; public $refTest2; public function __construct() { $this->refTest1 = new RefTest1($this->refTest2); $this->refTest2 = new RefTest2($this->refTest1); } public function changeReference() { $this->refTest1 = new RefTest3($this->refTest2); } } 

В конце RefTest1 содержит ссылку на RefTest2 и наоборот, также если объект RefTest2 не существовал в момент RefTest1 .

После вызова DoCrossRef->changeReference() объекты RefTest2 также содержат ссылку на новый объект RefTest3 .