2013-11-07 4 views
8

Я получаю смешанные сигналы повсюду.Должен ли я использовать амперсанд в PHP 5.5.X и выше?

Я использую амперсанд для передачи переменных по ссылке или нет?

Следующая ссылка, кажется, не говори мне, что она устарела и больше не нужны:
http://gtk.php.net/manual/en/html/tutorials/tutorials.changes.references.html

Но нити, как это делает меня удивление:
Call-time pass-by-reference deprecated?
PHP and ampersand

Позвольте мне фразу на мой вопрос В качестве примера.

Если я функцию, с помощью PHP 5.5.5:

function recurring_mailer_form($form, $form_state) 
{ 

} 

это то же самое, как:

function recurring_mailer_form($form, &$form_state) 
{ 

} 

?

+1

http://www.php.net/manual/en/language.references.pass.php –

+2

«И начиная с PHP 5.4.0 удаленная ссылка на вызов была удалена, поэтому ее использование повысит фатальная ошибка ». –

+1

@RUJordan «переадресация вызова времени» не является единственным видом передачи по ссылке. – IMSoP

ответ

22

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

Главное, что определяет, является ли параметр должен быть передан по ссылке является сама функция подписи, и основы этого не изменились с PHP 4. Рассмотрим следующий пример:

function foo($by_value, &$by_reference) { /* ... */ } 

$a = 1; $b = 2; 
foo($a, $b); 

Здесь внешняя переменная $a передается функции по значению, как если бы она была назначена как $by_value = $a; - изменения на $by_value не могут повлиять на $a. Переменная $b однако передается по ссылке; как и присвоение формы $by_reference =& $b;, это означает, что существует одна переменная, на которую ссылаются два имени, и любое присвоение одному будет действовать как назначение для обоих.

Если вы передаете «обычное» значение (строку, число или массив) по значению, его значение просто копируется в новую переменную. Начиная с PHP 5: Если вы передаете объект по значению, однако, происходит что-то немного другое - копирование «значение» - это просто указатель на тот же объект. Это означает, что если $a были объектом, вы могли бы позвонить $by_value->some_property = 42;, а $a->some_property также будет 42. Однако, если вы присвоили какое-то новое значение $by_value, оно все равно не повлияет на $a.

До PHP 5.4, не было дополнительный способ передать параметр по ссылке, которая должна была «сила» ссылка поведение на время вызова. Это означало, что вы могли написать foo(&$a, &$b); и «захватить» изменения, сделанные в $by_value внутри функции foo(). Опираясь на это, как правило, была плохая идея, и поэтому она была удалена. (Он высадился в 5.4, потому что он предназначался для удаления на PHP 6, но этот проект был поставлен на неопределенный срок, при этом небольшие изменения высаживались в 5.3 и 5.4).

И, наконец, функции могут return переменная по ссылке (как discussed in the manual here). Это немного затруднительно, так как на самом деле вам нужно поставить & в два мест: в начале объявления функции, чтобы сказать, что return должен означать «вернуть эту ссылку на переменные», а не «вернуть это значение»; и в коде, вызывающем его, назначить переменную этой ссылке, а не просто копировать ее значение. Вот простой пример, который сочетает в себе ссылочный параметр с обратной ссылкой (оба не должны идти вместе, это просто пример):

function &bar(&$some_param) { return $some_param; } 
$a = 1; 
$b =& bar($a); 
// $b and $a now point at the same variable, not just the same value 
// it was passed into and out of a function, and assigned to a new variable, 
// but all those operations were by reference 

Обратите внимание, что многие люди ошибочно полагают, что передача переменной по ссылке даст их преимущество в производительности, и это часто было их единственной причиной для использования переадресации вызова времени.На самом деле это обычно неправильно, поскольку Zend Engine, который использует PHP, использует метод «copy on write», чтобы оставить несколько переменных, которые имеют одинаковое значение, указывающее на одну и ту же часть памяти, даже если они не связаны как Рекомендации. Фактически, ссылочное задание обычно поражает этой оптимизацией из-за того, как двигатель отслеживает, какие переменные находятся в состоянии копирования на запись.

+0

Последний параграф о производительности важен, и то, что я здесь искал. Можете ли вы разместить некоторые ссылки на эти выводы? –

+0

@ T.BrianJones Если я думаю о том, где найти хорошие статьи, я их добавлю. Если вы хотите найти поиск, попробуйте найти «zval» и «copy on write». – IMSoP

1

Нет, это не то же самое. PHP 5.4+ просто определяет вызов, нужна ли ссылка при вызове функции, проверяя объявление.

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

+0

* Любая * версия PHP обнаруживает при вызове, нужна ли ссылка в соответствии с объявлением. Разница в том, что до PHP 5.4 вы могли * заставить * переменную, передаваемую по ссылке *, несмотря на * объявление функции. – IMSoP

2

Нет, это не так.

  • Объектов всегда автоматически передаются в качестве ссылок (информации см ниже для получения дополнительной важной информации!)

  • Объявления paramters в качестве ссылки должна произойти при определении функции:

    function test(&$var) {} 
    

    Не на момент его называния:

    // wrong 
    $var = '123'; 
    test(&$var); 
    


Если передать объект как обычно, вы можете изменить состояние объекта (свойства).
Предположим, что $obj является экземпляром класса TestClass, который содержит переменную-член под названием hello ( click here for a full sample at Ideone.com):

function modify($obj) { $obj->hello = 'world (modified)!'; } 

$obj->hello = 'world'; 
modify($obj); 
var_dump($obj->hello); // outputs "world (modified!)" 

Это должно быть очевидно.Теперь, используя один и тот же код, но назначить другое значение $obj вместо изменения состояния результатов объекта в каких-либо модификаций (→ Ideone.com):

function modify($obj) { $obj = 42; } 
// ... 
var_dump($obj->hello); // outputs "world" 

только принимать параметр в явном виде ссылка дает нам возможность полностью изменить содержимое переменной (→ Ideone.com):

function modify(&$obj) { $obj = 42; } 
// ... 
var_dump($obj);   // outputs "42" 
+2

«Объекты всегда автоматически передаются как ссылки» - это не совсем правильно (хотя руководство иногда говорит об этом). Если вы передадите переменную по ссылке, вы можете присвоить ее самой; если вы пройдете по значению, вы не сможете. Однако передача объекта по значению позволяет вам манипулировать * объектом *, используя оператор '->' и т. Д. – IMSoP

+1

@IMSoP Спасибо за ваш комментарий! Я обновил свой ответ. – ComFreek

+1

Хороший краткий пример :) Люди так часто пропускают разницу между модификацией объекта и модификацией переменной. – IMSoP

 Смежные вопросы

  • Нет связанных вопросов^_^