Может кто-нибудь объяснить, что делает «&» в следующем:
class TEST { } $abc =& new TEST();
Я знаю, что это по ссылке. Но может кто-нибудь проиллюстрировать, почему и когда мне понадобится такая вещь? Или укажите мне URL-адрес, где это объясняется хорошо. Я не могу понять концепцию.
Большое спасибо.
Насколько я понимаю, вы не спрашиваете о ссылках PHP вообще, а о $foo =& new Bar();
строительная идиома.
Это видно только в PHP4, поскольку обычный $foo = new Bar()
хранит копию объекта. Это обычно остается незамеченным, если класс не сохранил ссылку на $ this в конструкторе. При вызове метода по возвращенному объекту позже будет существовать две разные копии объекта, когда у намерения, вероятно, будет только одно.
Рассмотрим этот код, где конструктор хранит ссылку на $ this в глобальном var
class Bar { function Bar(){ $GLOBALS['copy']=&$this; $this->str="hello"; } } //store copy of constructed object $x=new Bar; $x->str="goodbye"; echo $copy->str."\n"; //hello echo $x->str."\n"; //goodbye //store reference to constructed object $x=&new Bar; $x->str="au revoir"; echo $copy->str."\n"; //au revoir echo $x->str."\n"; //au revoir
В первом примере $ x и $ copy ссылаются на разные экземпляры Foo, но во втором они одинаковы.
Во-первых, вам не нужно использовать его, если вы используете PHP 5, на PHP 5 все объекты по умолчанию передаются по ссылке.
Во-вторых, когда вы назначаете объект имени переменной, создавая, передавая параметр или устанавливая значение переменной, вы делаете это по ссылке или значению.
Передача по ссылке означает, что вы передаете фактическую ссылку на память для объекта, поэтому скажите, что вы передали объект в качестве параметра функции, любые изменения, которые функция делает для этой переменной, будут также отражаться в родительском методе, вы фактически меняете состояние этого объекта в памяти.
Альтернатива для передачи по значению означает, что вы передаете копию этого объекта, а не ссылку на память, поэтому любые сделанные вами изменения не будут отражаться в оригинале.
Руководство по PHP делает довольно приличную работу по объяснению ссылок.
Я должен отметить, что они не то же самое, что указатель или ссылка на многих других языках, хотя есть сходства. А что касается объектов, которые по умолчанию передаются по ссылке – это тоже не так.
Я бы порекомендовал сначала прочитать раздел руководства (и, вероятно, потом перечитывать пару раз, пока вы его не получите), а затем вернитесь сюда, если у вас еще больше вопросов.
Более простой способ взглянуть на это может быть следующим:
$a = 'foo'; $b = 'bar'; $a =& $b; $b = 'foobar'; echo $a . ' ' . $b;
выйдет
foobar foobar
Возможно, было бы полезно подумать об этом так: В PHP все переменные действительно являются своего рода указателем: записи в таблице символов – вещь, которая сопоставляет именам переменных со значениями – содержат zval *
в реализации C Zend Двигатель.
Во время назначения – это включает в себя настройку аргументов функции – произойдет волшебство:
Если вы сделаете $a = $b
, будет создана копия значения, обозначенного символьной табличной записью $b
, и указатель на это новое значение будет помещен в запись таблицы символов для $a
. Теперь $a
и $b
будут указывать на разные значения. PHP использует это как соглашение о вызове по умолчанию.
Если вы выполняете $a =& $b
, запись в таблице символов для $a
будет указана указателем, содержащимся в записи таблицы символов для $b
. Это означает, что $a
и $b
теперь указывают на одно и то же значение – они являются псевдонимами друг друга с равными правами, пока они не отскакивают от программиста. Также обратите внимание, что $a
самом деле не ссылается на $b
– они оба указывают на один и тот же объект.
Вот почему называть их «псевдонимами» может быть хорошей идеей, чтобы подчеркнуть различия с эталонной реализацией C ++:
В C ++ переменная, содержащая значение и ссылку, созданные из этой переменной, не равна – вот почему есть такие вещи, как оборванные ссылки.
Чтобы быть ясным: в PHP нет такой вещи, как ссылочный тип, поскольку все переменные уже внутренне реализованы как указатели, и поэтому каждый из них может выступать в качестве ссылки.
Объекты PHP5 по-прежнему согласуются с этим описанием – они не передаются по ссылке, а указатель на объект (руководство называет его «идентификатором объекта» – оно не может быть реализовано как фактический указатель C – я не проверял это) передается по значению (что означает копирование при назначении, как описано выше).
Подробнее о связи между объектами PHP5 и ссылками обратитесь к руководству.