Хочу рассказать Вам все о сайтах, что узнал сам за 10 лет.
Блог Виталия Жукова Vitalik.WS Свой сайт с нуля - легко!
Обо мне, как об авторе блога.
Подробнее
Vitalik.WSЗаметки → Использование амперсанда перед переменными, начиная с версии PHP 5.4

Использование амперсанда перед переменными, начиная с версии PHP 5.4
Заметка на тему: PHP

Все содержание этой заметки в общем-то будет построено вокруг одного символа - & или амперсанд. А связано это с тем, что этот символ имеет в PHP смысл оператора, под которым подразумевается какое-то действие (как, например, знак $, означающий начало переменной). И дословно это действие звучит как "передача данных по ссылке". Согласен, звучит немного не понятно, особенно когда вы только в начале пути изучения PHP. Поэтому я расскажу о смысле этого символа более развернуто и понятно.

Для чего нужен амперсанд в PHP?

Опираясь на официальную документацию по PHP, & (амперсанд) в PHP - это передача переменной по ссылке, о чем я уже упоминал. Можно почитать эту документацию, попытаться вникнуть, тем более сейчас там появилась русская версия, но я все-таки попытаюсь рассказать более подробно и понятно.

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

Возьмем для пример объявление простой переменной на PHP:
$testVar = "test text";

Логика тут проста: в PHP создается переменная $testVar и в нее записывается нужное значение (можно провести аналогию с контейнером, в который можно положить хоть что; каждая новая переменная при этом - отдельный контейнер).
Но что будет, если мы это чуть усложним и добавим символ &.
$testVar = "test text"; //то же самое, что и выше
//ставим ссылку на $testVar для переменной $otherV
$otherV = &$testVar;
//теперь $otherV выведет значение "test text"

Берет, ставит ссылку и дублирует значение - вроде бы понятно. Но возникает интересный вопрос - в чем разница между
$otherV = &$testVar и $otherV = $testVar

ведь и в том и в другом случае $otherV выведет значение "test text". И для ответа на него рассмотрим пример, озвученный в официальной документации:
//обратите внимание, что функция работает НЕ с новой переменной $var,
//а с ссылкой &$var, в нашем случае ссылка на $a
function foo(&$var)
{
  //прибавляем единицу для проверки, что изменится
  $var = $var+1;
}

$a=5;
foo($a);
//теперь в переменной $a значение будет равно уже 6

То есть внутри функции foo() мы изменяли $var, а поменялась $a. И это не магия, это смысл ссылки &$var, которая просто является промежуточным звеном между основной переменной и необходимыми действиями.

Уберите этот символ & перед $var - в конце кода вы увидите, что $a останется = 5, так как в данном случае $var будет уже новой переменной со значением 5 (закованной внутри функции) и её изменения никак не затронут $a.

Ошибка "Fatal error: Call-time pass-by-reference has been removed in ... on line XXX"

Мы подобрались к проблеме, которая появилась в PHP 5.4+ версии. Как вы догадываетесь - её суть все в том же символе & (амперсанд), который задает, является ли данная переменная ссылкой на другую переменную или нет.

Возьмем для примера ту же функцию, что чуть выше:
function foo(&$var)
{
  $var = $var+1;
}
 
$a=5;
foo($a);

Тут показано правильное использование амперсанда (при объявлении переменных функции). Этот пример будет работать БЕЗ ошибки.

Но для возникновения критической ошибки "Fatal error: Call-time pass-by-reference has been removed in ..." достаточно сделать вот так:
function foo(&$var)
{
  $var = $var+1;
}
 
$a=5;
foo(&$a);//ошибка в этом месте, нельзя прописывать ссылку на этом этапе

То есть при вызове функции foo() указана ссылка и это НЕ правильно и приводит к ошибке. Для устранения ошибки достаточно убрать символ & из вызова функции, то бишь заменить:
foo(&$a);

на
foo($a);


На этом вроде бы все. Теперь, я думаю, должно появиться общее понятие о том, для чего нужен & (амперсанд) в PHP, а так же о том, как исправить или не допустить фатальную ошибку "call-time pass-by-reference has been removed in ...". Не ленитесь экспериментировать и опирайтесь на официальную документацию.

Вопросы можете задавать в комментариях. Специально для Вас, Vitalik.

Все комментарии к заметке "Использование амперсанда перед переменными, начиная с версии PHP 5.4"

  • Алексей
    Ответить
    Комментарий #61.4
    Спасибо, очень доходчиво объяснили
    добавлен 20 октября 2016 в 14:04
Написать свой комментарий:
Отправить
ВНИМАНИЕ! Пожалуйста НЕ пишите в комментариях рекламу, оскорбления, бессмыслицу и прочие проявления интернет-нечисти, так как эти сообщения всеравно не будут опубликованы. Пишите исключительно по теме и ваш комментарий обязательно будет опубликован, а возможно и прокомментирован.
 Подписывайтесь на мой блог
Хотите первыми узнавать о самом интересном? Тогда подпишитесь на рассылку новостей.
Подписаться
Подписавшись на рассылку, Вы всегда будете в первую очередь узнавать о самой важной и полезной для блоггеров и веб-мастеров информации.