PHP: Почему только переменные должны передаваться по ссылке? - PullRequest
0 голосов
/ 04 сентября 2018

Если вы являетесь разработчиком PHP, вы, скорее всего, видели следующее уведомление:

Примечание: только переменные должны передаваться по ссылке в /somefile.php на линии ххх

(Проблема экстенсивли обработана в Только переменные должны передаваться по ссылке )

Пример уведомления о броске:

$string = "hi-dude";
echo end(explode('-', $string));

Рабочий пример:

$string = "hi-dude";
$strings = explode('-', $string);
echo end($strings);

Пояснение:

Только реальные переменные могут передаваться по ссылке, но не функции, которые возвращают правильную переменную.

Однако я не могу придумать вескую причину, по которой происходит это уведомление. В этом нет необходимости, и иногда мне приходится писать много лишних строк кода. В чем причина такого странного ограничения PHP? Почему эта проблема вообще существует?

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

Наконец я нашел отличное объяснение, которое помогло мне понять это: В чем разница между передачей по ссылке и передачей по значению?

Как утверждает Даниэль Приден:

Проще говоря:

  • вызов по значению означает, что вы передаете значения в качестве аргументов функции
  • вызов по ссылке означает, что вы передаете переменные в качестве аргументов функции

В переносном смысле:

  • Вызов по значению - это то, где я записываю что-то на листе бумаги и передаю вам. Может быть, это URL, может быть, это полная копия Война и мир. Неважно, что это, это на листе бумаги, который Я дал вам, и теперь это фактически ваш лист бумаги. Теперь вы можете делать наброски на этом листе бумаги или использовать его бумаги, чтобы найти что-то еще и возиться с этим, что угодно.
  • Звонок по ссылке - это когда я даю вам свой блокнот, в котором что-то записано. Вы можете писать в моей записной книжке (может быть, я Я хочу, чтобы вы, возможно, я не), а потом я держу свой блокнот, с какие бы каракули вы там ни ставили. Кроме того, если что либо ты или я там написано есть информация о том, как найти что-то еще, вы или я можем пойти туда и поиграть с этой информацией.

В этом случае уведомление «Только переменные должны передаваться по ссылке» по-прежнему неоправданно , поскольку мы заинтересованы только в получении последнего значения массива. Однако функция end() определяется как

смешанный конец (массив и $ массив)

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

Если бы мы только возвращали последний элемент массива, не касаясь массива, не было бы необходимости передавать массив по ссылке, и мы не получили бы это уведомление. Но end() как-то не подходит для этого.

Что делать, если я не получу этого уведомления? Обратите внимание, что также вызываемая функция может быть определена неправильно. В моем случае я использовал функцию, определенную так:

/**
 * Flatten an array by one level if only needing a certain key value from a sub array.
 *
 * Example: [["foo"=>"bar","foo"=>"cheese"]]
 * Result: ["bar","cheese"]
 *
 * @param $array: The input array.
 * @param $key: The key to flatupshift. Default is 0.
 * @return $array: The result
 */
private function array_flatupshift(&$array, $key = 0) {
    $a = [];
    foreach ($array as $item) {
        if (is_object($item)) {
            array_push($a, $item->$key);
        } else if (is_array($item)) {
            array_push($a, $item[$key]);
        }
    }
    return $a;
}

Это просто неправильное определение функции. Так что, если вы также получаете уведомления, подобные следующему: Проверьте, правильно ли вызвана вызываемая вами функция. Передача по ссылке здесь не имеет смысла, поскольку передаваемый массив не затрагивается никоим образом , Поэтому определение функции должно быть без «ссылки & /»:

private function array_flatupshift($array, $key = 0) {

В некоторых случаях вы МОЖЕТЕ использовать оператор контроля ошибок, если знаете, что делаете. Поэтому:

$string = "hi-dude";
echo @end(explode('-', $string));

... было бы хорошо Я думаю, что результат взрыва больше не нужен. Однако обратите внимание на недостатки подавления всех возможных ошибок. Пожалуйста, поправьте меня, если я ошибусь здесь.

0 голосов
/ 04 сентября 2018

end() или array_pop() вернет E_NOTICE с сообщением

Только переменные должны передаваться по ссылке

Причина в том, что для end() требуется ссылка, поскольку указатель текущего элемента указывает на последний элемент.

Вы можете сделать это одной строкой,

$string = "this-is-a-sample-text";
echo substr(strrchr($string, '-'), 1);

DEMO: https://3v4l.org/jO29n

...