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

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

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

function foo(TypeName& $obj)

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

function foo(TypeName $obj)

Итак, что говорит стандарт?

Ответ 1

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

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

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

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

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

Ответ 2

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

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

<?php
function foo(&$var)
{
    $var++;
}

$a=5;
foo($a);
// $a is 6 here
?>

Примечание: на вызов функции - только по функции определения. Определения функций достаточно, чтобы правильно пройти аргумент по ссылке. Начиная с PHP 5.3.0, вы получите предупреждение о том, что "время вызова по ссылке" устарел при использовании и в Foo (& $а);.

И из Что нового в PHP5:

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

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

Ответ 3

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

В 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...
?> 

Ответ 4

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

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

Ответ 5

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

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

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

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

Ответ 6

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

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

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

Ответ 7

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

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.