Как вы передаете объекты по ссылке в PHP 5? - PullRequest
22 голосов
/ 17 февраля 2012

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

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

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

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

Ответы [ 3 ]

80 голосов
/ 17 февраля 2012

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

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

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 является целым числом. Таким образом, существует разница между передачей по идентификатору и передачей по reference .

0 голосов
/ 17 февраля 2012

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

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

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

$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.
0 голосов
/ 17 февраля 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);
...