Php по ссылке - PullRequest
       37

Php по ссылке

3 голосов
/ 24 января 2009

Может кто-нибудь объяснить, что "&" делает в следующем:

class TEST {

}

$abc =& new TEST();

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

Большое спасибо.

Ответы [ 5 ]

11 голосов
/ 24 января 2009

Насколько я понимаю, вы спрашиваете не о ссылках на PHP вообще, а о идиоме конструкции $foo =& new Bar();.

Это видно только в PHP4, как обычно $foo = new Bar() хранит копию объекта. Обычно это остается незамеченным, если класс не хранит ссылку на $ this в конструкторе. При последующем вызове метода для возвращаемого объекта будут существовать две отдельные копии объекта, когда намерение, вероятно, будет иметь только одну.

Рассмотрим этот код, где конструктор хранит ссылку на $ this в глобальной переменной

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, но во втором они совпадают.

1 голос
/ 24 января 2009

Руководство по PHP довольно неплохо объясняет ссылки.

Я должен отметить, что они НЕ - это то же самое, что указатель или ссылка во многих других языках, хотя есть сходства. А что касается объектов, которые «передаются по ссылке» по умолчанию - это тоже не совсем так.

Я бы рекомендовал сначала прочитать раздел руководства (и, возможно, затем перечитать пару раз, пока не получите его), а затем вернуться сюда, если у вас остались вопросы.

1 голос
/ 24 января 2009

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

Во-вторых, когда вы назначаете объект имени переменной, либо путем создания, передачи параметра или установки значения переменной, вы делаете это либо по ссылке, либо по значению.

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

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

0 голосов
/ 24 января 2009

Может быть полезно думать об этом так: в PHP все переменные действительно являются своего рода указателем: записи в таблице символов - то, что отображает имена переменных в значения - содержат zval * в C реализация Zend Engine.

Во время присваивания - это включает установку аргументов функции - произойдет волшебство:

Если вы сделаете $a = $b, будет создана копия значения, на которое указывает запись в таблице символов $b, и указатель на это новое значение будет помещен в запись таблицы символов для $a. Теперь $a и $b будут указывать на разные значения. PHP использует это как соглашение о вызовах по умолчанию.

Если вы сделаете $a =& $b, запись таблицы символов для $a будет установлена ​​на указатель, содержащийся в записи таблицы символов для $b. Это означает, что $a и $b теперь указывают на одно и то же значение - они являются псевдонимами друг друга с равными правами, пока программист не восстановит их. Также обратите внимание, что $a на самом деле не является ссылкой на $b - они оба являются указателями на один и тот же объект.

Вот почему называть их «псевдонимами» может быть хорошей идеей, чтобы подчеркнуть различия с эталонной реализацией C ++:

В C ++ переменная, содержащая значение и ссылку, созданную из этой переменной, не равны - вот почему существуют такие вещи, как висячие ссылки.

Для ясности: в PHP нет такого понятия, как ссылочный тип, поскольку все переменные уже реализованы внутри как указатели, и поэтому каждая из них может действовать как ссылка.

Объекты PHP5 по-прежнему согласуются с этим описанием - они не передаются по ссылке, но указатель на объект (руководство называет его «идентификатором объекта» - это может не должен быть реализован как фактический указатель C - я не проверял это) передается значением (имеется в виду, скопировано при назначении, как описано выше).

Проверьте в руководстве подробности о связи между объектами PHP5 и ссылками .

0 голосов
/ 24 января 2009

Более простой взгляд на это может быть следующим:

$a = 'foo';
$b = 'bar';
$a =& $b;
$b = 'foobar';
echo $a . ' ' . $b;

выдаст

foobar foobar
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...