Я не могу понять логику оценки в коде, указанном ниже. Кто-нибудь знает, почему PHP оценивает $b
а также $b = $b
иначе в этом случае?
Я прочитал несколько вопросов здесь в SO и проверил Руководство по PHP. Поступая так, я понял, что «PHP (в общем случае) не указывает, в каком порядке вычисляется выражение» и это «поведение может меняться между версиями PHP или в зависимости от окружающего кода». Я не чувствую, что это относится к этой ситуации, хотя. Или это?
Будучи первым, кто признает, что это не может быть вашей повседневной проблемой кодирования, мне все равно любопытно. Наткнулся на это, пытаясь сделать некоторые код игры в гольф.
$a = [[00, 01, 02, 03],
[10, 11, 12, 13],
[20, 21, 22, 23],
[30, 31, 32, 33]];
$b = 2;
echo $a[$b][$b++], PHP_EOL;
$b = 2;
echo $a[$b=$b][$b++], PHP_EOL;
Вывод — PHP 5.5.14:
32
22
Это похоже на пример в руководство используется для демонстрации Неопределенный порядок оценки. Из руководства:
Приоритет оператора и ассоциативность определяют только то, как сгруппированы выражения, но не определяют порядок вычисления. PHP (в общем случае) не указывает, в каком порядке вычисляется выражение, и следует избегать кода, предполагающего определенный порядок вычисления, поскольку поведение может изменяться между версиями PHP или в зависимости от окружающего кода.
Акцент добавлен
Пример, который они дают:
<?php
$a = 1;
echo $a + $a++; // may print either 2 or 3
$i = 1;
$array[$i] = $i++; // may set either index 1 or 2
?>
Вы получаете результат, который вы есть, потому что в первом примере индекс $b++
определяется первый, тогда как во втором индекс $b=$b
это первое.
NB
Что касается Зачем это, я полагаю, одна из возможных причин объясняется этой заметкой на той же странице руководства:
Хотя = имеет более низкий приоритет, чем большинство других операторов, PHP по-прежнему допускает выражения, подобные следующим: if (! $ A = foo ()), и в этом случае возвращаемое значение foo () помещается в $ a.
Я полагаю, что им не хватает решающего последнего слова: первый (без, для меня чтение заметки теряет смысл).
Следуя собственным правилам PHP, а также мы принимаем заказ FIFO, !$a
должны быть оценены в первую очередь. Если $a
Сейчас null
или же undefined
, затем !$a
будет равно true
(оно будет оценено, и этот результат будет отброшен). После этого foo()
будет оцениваться, и его возвращаемое значение будет присвоено $a
(даже если мы принимаем FIFO, foo()
должен быть оценен первым, если его результат должен быть назначен чему-либо). Результат этого задания будет оцениваться if
и приведет к совершенно противоположному значению, которое хотел автор.
Я не эксперт по Си, но немного поисков также привело меня к этому ответ который цитирует стандарт C90:
(C90, 6.3) «За исключением случаев, обозначенных синтаксисом или иным образом заданных позже (для оператора вызова функции (), &&, ||,?: и операторы запятой). порядок вычисления подвыражений и порядок возникновения побочных эффектов не определены «
Поскольку PHP построен на C, имеет смысл наследовать некоторые его эксцентриситеты.
Других решений пока нет …