Последнее обновление статьи — 15 декабря 2018
Микрозаметка на тему из области «вопросы на собеседовании».
Как-то я в PHP
начал писать and
и or
вместо &&
и ||
, потому что мне так нравится делать на питоне, и, как я думал, это улучшает читабельность кода. Однажды я столкнулся с неожиданным эффектом:
1 2 3 | // Переменная $has_place получает неверное значение // при $row->archive === 0 и $row->available_qty > 0 $has_place = ((int)$row->archive === 0) and ((int)$row->available_qty > 0); |
Как оказалось, логические операторы and
и &&
(or
и ||
) не являются просто синонимами, а имеют разный приоритет выполнения: все «символьные» (&&, ||, !
) операторы выполняются до оператора присваивания =
, а and, or, xor
— после.
Подробно об этом написано в официальной документации.
Что это значит на практике:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /* AND */ // Как ожидается: $var = (true && false) === false $var = true && false; // Константа true присваивается $var, а затем значение false игнорируется // Действует как: (($var = true) and false) $var = true and false; // $var === true ! /* OR */ // Как ожидается: $var = (false || true) === true $var = false || true; // Константа false присваивается $var, а затем значение true игнорируется // Действует как: (($var = false) or true) $var = false or true; // $var === false ! |
Вывод такой: если пользоваться читабельными вариантами логических операторов в условиях, всё будет работать, как ожидалось. В случаях, где результат выражения должен быть присвоен или возвращён, стоит следить внимательней за порядком выполнения выражений — именно поэтому линтеры/статические анализаторы выдают предупреждение на подобных участках кода, и рекомендуют переписать его в стандартном виде.