Вернуться по ссылке в PHP - PullRequest
24 голосов
/ 17 сентября 2011

Я попробовал Googling, попробовал PHP документацию, искал Stack Overflow для ответа, но не смог найти ничего удовлетворительного. Я читал книгу, в которой автор использовал функцию «Возвращение по ссылке», но никогда не объяснял, что это такое. Код, использованный автором:

function &getSchool() {
    return $this->school;
}

Может кто-нибудь объяснить простыми словами на примере этой концепции.

Ответы [ 3 ]

32 голосов
/ 17 сентября 2011

Предположим, у вас есть этот класс:

class Fruit {
    private $color = "red";

    public function getColor() {
        return $this->color;
    }

    public function &getColorByRef() {
        return $this->color;
    }
} 

У класса есть личное свойство и два метода, которые позволяют вам получить к нему доступ.Один возвращает по значению (поведение по умолчанию), а другой по ссылке.Разница между ними заключается в том, что:

  • При использовании первого метода вы можете вносить изменения в возвращаемое значение, и эти изменения не будут отражены в частном свойстве Fruit, потому что вы на самом делеизменение копии значения свойства.
  • При использовании второго метода вы фактически получаете псевдоним для Fruit::$color - другое имя с помощьюкоторый вы ссылаетесь на той же переменной .Поэтому, если вы что-то делаете с ним (включая изменение его содержимого), вы фактически выполняете то же действие со значением свойства.

Вот некоторый код для его проверки:

echo "\nTEST RUN 1:\n\n";
$fruit = new Fruit;
$color = $fruit->getColor();
echo "Fruit's color is $color\n"; 
$color = "green"; // does nothing, but bear with me
$color = $fruit->getColor();
echo "Fruit's color is $color\n"; 

echo "\nTEST RUN 2:\n\n";
$fruit = new Fruit;
$color = &$fruit->getColorByRef(); // also need to put & here
echo "Fruit's color is $color\n"; 
$color = "green"; // now this changes the actual property of $fruit
$color = $fruit->getColor();
echo "Fruit's color is $color\n"; 

См. Это в действии .

Предупреждение: Я чувствую себя обязанным упомянуть, что ссылки, хотя они действительно используются,являются одной из тех функций, которые следует использовать только в редких случаях и только в том случае, если вы сначала тщательно рассмотрели любые альтернативы .Менее опытные программисты склонны злоупотреблять ссылками, потому что они видят, что могут помочь им решить конкретную проблему, не видя при этом недостатков в использовании ссылок (в качестве дополнительной функции ее нюансы далеко не очевидны).

14 голосов
/ 30 января 2013

Простое правило : если вы поместите & перед именем функции в PHP, вы можете использовать & при вызове функции (т.е. это возвращаемое значение), как если бы она была переменная, а не функция.

Вот и все.


Проще думать, что это «PHP, позволяющий вам ссылаться на возвращаемое значение», а не PHP, возвращаемый по ссылке. Как упоминалось выше, вы просто помещаете &, чтобы сообщить PHP, что вы этого хотите, если вы не разместите его и попытаетесь выполнить команду $var =& somefunction(), вы получите ошибку «Только переменные должны быть назначены по ссылке».

Чтобы устранить путаницу с ответом Джона. На самом деле нет необходимости иметь две отдельные функции, одна из которых возвращается по ссылке, а другая - по значению; вне какой-то конвенции проекта. & only позволяет ему возвращаться по ссылке, не заставляет возвращаться по ссылке.

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

\header('content-type: text/plain');

class Demo
{
    protected $example = 'original value';

    function & example()
    {
        return $this->example;
    }
}

$demo = new Demo;

#1 - pass by value

$var1 = $demo->example();
$var1 = 'var1 value';

echo '$demo->example() => '.$demo->example().PHP_EOL;
echo PHP_EOL;

#2 - pass by reference

$var2 =& $demo->example();
$var2 = 'var2 value';

echo '$demo->example() => '.$demo->example().PHP_EOL;
echo '$var1 => '.$var1.PHP_EOL;
echo '$var2 => '.$var2.PHP_EOL;
echo PHP_EOL;

#3 - altering other references

$var3 =& $demo->example();
$var3 = 'var3 value';

echo '$demo->example() => '.$demo->example().PHP_EOL;
echo '$var1 => '.$var1.PHP_EOL;
echo '$var2 => '.$var2.PHP_EOL;
echo '$var3 => '.$var3.PHP_EOL;
echo PHP_EOL;

exit;

выход

$demo->example() => original value

$demo->example() => var2 value
$var1 => var1 value
$var2 => var2 value

$demo->example() => var3 value
$var1 => var1 value
$var2 => var3 value
$var3 => var3 value

Ссылки являются отличными, однако, если вы не знакомы с ними, пожалуйста, следуйте следующим правилам:

  • рассмотрите возможность использования ссылок, только если вы имеете дело с большим массивом или подобными необъектными структурами данных
  • никогда не ссылаться на объект (если вы можете избежать его)
  • разрешает передачу функции только по ссылке, если значение поддерживается в статическом свойстве или атрибуте объекта (т. Е. Это не временная переменная внутри функции)

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

Опять же, НИКОГДА НЕ ОБРАЩАЕТСЯ К ОБЪЕКТАМ (это бессмысленно!)

3 голосов
/ 17 сентября 2011

Пример, который вы разместили, возможно, написан на PHP4 или более ранней версии. Больше нет необходимости возвращать объекты по ссылке, поскольку они почти всегда выполняются таким образом автоматически в PHP5 +.

Возвращение по ссылке полезно, если вы хотите использовать функцию для найдите, к какой переменной должна быть привязана ссылка. Не использовать возврат по ссылке для повышения производительности. Двигатель будет автоматически оптимизировать это самостоятельно. Вернуть ссылки только тогда, когда у вас есть веская техническая причина для этого.

См. возврат ссылок в документах PHP

...