Почему мой оператор IF ($ a || $ b && $ c) не работает должным образом (приоритет оператора PHP) - PullRequest
0 голосов
/ 20 марта 2019

За прошедшие годы я заметил, что многие PHP-программисты не понимают, как важно всегда ставить круглые скобки, даже если это «не нужно». (подсказка: это всегда необходимо)

Пример сценария:

Вам поручено обновить страницу входа в систему, чтобы разрешить использование либо существующего пароля, либо токена входа в систему с именем пользователя.

Существующий код выглядит примерно так:

if ($password_is_valid && $username_is_valid) {
    // Success
} else {
    // Failure
}

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

if ($password_is_valid || $token_is_valid && $username_is_valid) {
    // Success
} else {
    // Failure
}

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

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

Как это возможно?


Обратите внимание: Этот пост предназначен исключительно для того, чтобы помочь начинающим / менее опытным разработчикам с общей проблемой, основанной на недопонимании того, как && и || работают вместе. Я попытался найти похожий пост на S.O. однако я не смог найти его, или, по крайней мере, не для PHP.

1 Ответ

2 голосов
/ 20 марта 2019

Короткий ответ: вы неправильно понимаете , как работает приоритет операторов в PHP .Однако это объяснение слишком подробное и выходит за рамки этого вопроса.

Самый простой и лучший ответ - всегда использовать круглые скобки при операциях смешения И / ИЛИ всякий раз, когда это возможно.непонятно, что следует оценивать в первую очередь.

В контексте нашего примера сценария обновленный код должен выглядеть следующим образом:

if (($password_is_valid || $token_is_valid) && $username_is_valid) {
    // Success
} else {
    // Failure
}

Однако, посколькуобновленный код не содержит скобок для указания порядка запуска операций , PHP интерпретирует это так: :

if ($password_is_valid || ($token_is_valid && $username_is_valid)) {
    // Success
} else {
    // Failure
}

Если вы все еще не уверены, этопример кода, с которым вы можете поиграть, чтобы лучше понять эту проблему: https://3v4l.org/SmIip

Более того , даже когда скобки "действительно не нужны для функционирования в качестветребуемый " они сделают ваш код более читабельным и более легким для понимания.Что будет важно для следующего разработчика, который будет читать ваш код.(На самом деле это могут быть люди старше 6 месяцев, когда вы забыли, о чем думали, когда писали это.) Поэтому всегда добавляйте их, даже если вы уверены, что они «не нужны».

...