为什么我的IF($ a || $ b && $ c)语句不能按预期工作(PHP运算符优先级)

问题描述 投票:-1回答:1

多年来,我注意到有很多PHP程序员不了解确保始终包含括号的重要性,即使“不需要”也是如此。 (提示:总是需要)

Example Scenario:

您的任务是更新登录页面以允许使用其现有密码或使用用户名的登录令牌。

现有代码看起来像这样:

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

您将代码更新为如下所示:

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

经过几次测试以确保用户仍然可以登录,您确认一切顺利,并将其称为一天。快进几周或几个月,您的经理正在大吼大叫,了解一位销售人员如何能够以管理员身份登录并在不知道管理员密码的情况下自行加薪。

阅读完所有登录代码3次后,您完全不知道如何发生这种情况。最后,您需要进行一些手动测试,最终您会发现任何人的正确密码都可以与其他人的用户名一起使用,只要该用户名实际存在于数据库中即可。

这怎么可能?


请注意:这篇文章纯粹是为了帮助那些基于对&&||如何协同工作的误解而出现常见问题的新手/经验不足的开发人员。我确实试图在S.O.上找到类似的帖子。但是我无法找到一个,或者至少不能找到PHP。

php if-statement operator-precedence
1个回答
2
投票

简短的回答是你误解了how operator precedence works in 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个月以上。)所以只要总是添加它们,即使你确定“不需要它们”。

© www.soinside.com 2019 - 2024. All rights reserved.