порядок оценки — почему PHP по-разному оценивает $ b и $ b = $ b при использовании с $ b ++ в индексе массива

Я не могу понять логику оценки в коде, указанном ниже. Кто-нибудь знает, почему 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

5

Решение

Это похоже на пример в руководство используется для демонстрации Неопределенный порядок оценки. Из руководства:

Приоритет оператора и ассоциативность определяют только то, как сгруппированы выражения, но не определяют порядок вычисления. 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, имеет смысл наследовать некоторые его эксцентриситеты.

10

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]