Как вы передаете объекты по ссылке в PHP 5?

Обязательно ли в PHP 5 использовать модификатор & для передачи по ссылке? Например,

class People() { }
$p = new People();
function one($a) { $a = null; }
function two(&$a) { $a = null; )

В PHP4 вам нужен модификатор & для сохранения ссылки после внесения изменений, но я запутался в темах, которые я читал об автоматическом использовании передачи по ссылке в PHP5, за исключением случаев явного клонирования объекта.

В PHP5 требуется ли модификатор & для передачи по ссылке для всех типов объектов (переменных, классов, массивов и т. д.)?


person Brian Graham    schedule 17.02.2012    source источник
comment
Мануал решит все ваши проблемы. php.net/manual/en/language.oop5.references.php   -  person rdlowrey    schedule 17.02.2012


Ответы (3)


Вы должны использовать модификатор & для передачи по ссылке?

Технически/семантически ответ да, даже с объектами. Это связано с тем, что существует два способа передачи/назначения объекта: по ссылке или по идентификатору. Когда объявление функции содержит &, например:

function func(&$obj) {}

Аргумент будет передан по ссылке, несмотря ни на что. Если вы объявите без &

function func($obj) {}

Все будет передаваться по значению, за исключением объектов и ресурсов, которые затем будут передаваться через идентификатор. Что такое идентификатор? Ну, вы можете думать об этом как о ссылке на ссылку. Возьмем следующий пример:

class A
{
    public $v = 1;
}

function change($obj)
{
    $obj->v = 2;
}

function makezero($obj)
{
    $obj = 0;
}

$a = new A();

change($a);

var_dump($a); 

/* 
output:

object(A)#1 (1) {
  ["v"]=>
  int(2)
}

*/

makezero($a);

var_dump($a);

/* 
output (same as before):

object(A)#1 (1) {
  ["v"]=>
  int(2)
}

*/

Так почему же $a внезапно не становится целым числом после передачи его в makezero? Это потому, что мы перезаписали только идентификатор. Если бы мы прошли по ссылке:

function makezero(&$obj)
{
    $obj = 0;
}

makezero($a);

var_dump($a);

/* 
output:

int(0) 

*/

Теперь $a является целым числом. Итак, есть разница между передачей через идентификатор и передачей через ссылку.

person webbiedave    schedule 17.02.2012
comment
Спасибо за объяснение разницы между идентификаторами и ссылками, в руководстве это не очень понятно. - person Brian Graham; 17.02.2012
comment
Так же по умолчанию передаются объекты javascript. - person Alex_Nabu; 25.07.2015
comment
Извините, но не могли бы вы пояснить, почему сработало change(), а не makezero()? Вам не хватает & входа в систему change ()? Также я думаю, что в makezero вы хотите изменить $obj = 0; к $obj-›v = 0 - person Andrew; 07.10.2016
comment
Подводя итог и рассортировав все это в моей голове: все, что не является объектом или ресурсом, передается по значению, если явно не указано с помощью &, верно? По умолчанию объекты и ресурсы передаются по идентификатору. И мы могли бы думать об идентификаторе как о синониме псевдонима, верно? Псевдоним можно использовать для управления объектом, но он НЕ является объектом. - person Ignacio Segura; 10.11.2016

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

Что происходит за кулисами, так это то, что когда вы передаете переменную, содержащую объект, это ссылка на объект. Таким образом, сама переменная копируется, но по-прежнему ссылается на тот же объект. Итак, по сути есть две переменные, но обе указывают на один и тот же объект. Изменения, внесенные в объекты внутри функции, сохранятся.

В случае кода, который у вас есть (сначала вам нужен $ даже с &):

$original = new Object();

one($original); //$original unaffected
two($original); //$original will now be null

function one($a) { $a = null; } //This one has no impact on your original variable, it will still point to the object

function two(&$a) { $a = null; ) //This one will set your original variable to null, you'll lose the reference to the object.
person Chris    schedule 17.02.2012
comment
Таким образом, целые числа, строки, символы и логические значения передаются по значению, если только не используется модификатор &? - person Brian Graham; 17.02.2012
comment
@ Брайан Грэм, да. Если вы знакомы с указателями в C/C++, $original в предыдущем примере выглядит примерно так. Он содержит адрес созданного нами Объекта. Сам $original копируется при передаче в функцию one($a), но поскольку он содержит адрес, копия указывает на тот же объект. - person Chris; 17.02.2012
comment
Вы говорите, что в PHP5 объекты передаются по ссылке, верно? Тогда почему вы используете модификатор &, чтобы доказать свою точку зрения, если он не нужен, это не помогает мне понять мой вопрос. - person Brian Graham; 17.02.2012
comment
@BrianGraham Это техническое уточнение, вы можете рассматривать объекты как передаваемые по ссылке, но я раскрывал более технические аспекты работы системы. - person Chris; 17.02.2012
comment
Объекты на самом деле не передаются по ссылке. Равенство между переменной и объектом по существу передает ссылку на него. Эта же операция передачи по значению во время вызова функции, т.е. $obj=$passedObject приводит к $obj=&passedObjects - person SoWhat; 17.02.2012
comment
@SomeshMukherjee Насколько я понимаю, $obj = $passedObject, если мы установим $obj = null, $passedObject != null. Но если $obj = &$passedObject и вы установили $obj = null, теперь $passedObject == null. - person Chris; 17.02.2012
comment
Это то, что я имел в виду. Я перестарался со знаком &$. Я думаю, что на самом деле происходит то, что передается копия ссылки. Таким образом, установка ссылки на null или что-либо еще просто изменяет объект, который идентифицирует ссылка, а не сам объект. - person SoWhat; 17.02.2012

Вы используете это неправильно. Знак $ обязателен для любой переменной. Это должно быть: http://php.net/manual/en/language.references.pass.php

function foo(&$a)
{
$a=null;
}


foo($a);
To return a reference, use

 function &bar($a){
$a=5;
return $a

 }

В объектах и ​​массивах ссылка на объект копируется как формальный параметр, любые операции равенства двух объектов являются обменом ссылками.

$a=new People();
$b=$a;//equivalent to &$b=&$a roughly. That is the address of $b is the same as that of $a 

function goo($obj){
//$obj=$e(below) which essentially passes a reference of $e to $obj. For a basic datatype such as string, integer, bool, this would copy the value, but since equality between objects is anyways by references, this results in $obj as a reference to $e
}
$e=new People();
goo($e);
person SoWhat    schedule 17.02.2012
comment
Я забыл знак $, извините. - person Brian Graham; 17.02.2012