Как вы передаете объекты по ссылке в PHP 5?
В PHP 5 требуется ли вам использовать &
модификатор передать по ссылке? Например,
class People() { }
$p = new People();
function one($a) { $a = null; }
function two(&$a) { $a = null; )
В PHP4 вам нужно было &
Модификатор для сохранения ссылки после внесения изменений, но я запутался в темах, которые я читал, относительно автоматического использования передачи по ссылке в PHP5, за исключением случаев, когда клонирование объекта выполняется в явном виде.
В PHP5 это &
модификатор требуется передать по ссылке для всех типов объектов (переменных, классов, массивов, ...)?
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
является целым числом Таким образом, существует разница между передачей по идентификатору и передачей по ссылке.
Объекты будут передаваться по ссылке. Встроенные типы будут передаваться по значению (копироваться);
За кулисами происходит то, что когда вы передаете переменную, которая содержит объект, это ссылка на объект. Таким образом, сама переменная копируется, но она все еще ссылается на тот же объект. Итак, по сути, есть две переменные, но обе указывают на один и тот же объект. Изменения, внесенные в объекты внутри функции, сохранятся.
В случае кода, который у вас есть (сначала вам нужно $ даже с &):
$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.
Вы используете это неправильно. Знак $ обязателен для любой переменной. Это должно быть: 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);