php if 语句的评估序列

php evaluation sequence of if-statements

我在清理用户输入时遇到问题,我不知道 POST-数据是否已发送。当我这样做是为了检查:

if ($_POST["somedata"] == 2)
  DoSomething();

我会收到 error_reporint = E_ALL 的错误通知,可能未定义 $_POST["somedata"](例如,当加载页面时没有表单)。

所以我现在做这个检查:

if (isset($_POST["somedata"]) && $_POST["somedata"] == 2)
  DoSomething();

这不会输出错误,但对我来说它看起来很不稳定。我不确定我的 PHP-Version 是运气还是语句的简单性。当 if 语句更复杂时,只要这两项的顺序相同,使用它是否也安全?与所有 PHP- 版本一起使用是否安全?

我们在工作中使用它已经有一段时间了,在代码中可以追溯到几年前。使用起来很好,因为它首先检查变量是否确实存在,然后才检查它是否有值。

您的代码片段是正确的。

    if (isset($_POST["somedata"]) && $_POST["somedata"] == 2)
            DoSomething();

我强烈建议您使用三等号进行质量检查。查看 How do the PHP equality (== double equals) and identity (=== triple equals) comparison operators differ? 了解有关相等性检查的更多信息。

三等号意味着它需要是一个整数而不仅仅是一个字符串,这是开始这样做的好习惯。

结合使用 isset 和惰性与 (&&) 是相对正确的(它可以防止严格警告)。一种更高级的方法是根据模式或模型进行自动输入检查。

你可以:

$schema = array(
    "somedata" => "number"
);

使用模式方法需要一点架构,但它消除了您可能担心的不稳定性。


值得一提的是,语法级别的输入验证(我是否获得了所有必需的输入)和语义级别的输入验证之间存在差异。假设您有一个名为 GetItem 的服务并且您传递了 id = 3 语法检查器将检查是否存在 id 属性 并且它是一个数字。然后你需要检查3是否真的存在

因此,与其 returning invalid request (bad input),不如 return no such item

您的方法在功能上是正确的,因为如果第一项的计算结果为 false,&& 就会短路。关于稳定性,正如您所怀疑的那样,有一个小问题,特别是与代码重复有关,主要是您需要始终注意两个键匹配相同的字符串(可以说这是代码重复的问题)。

一种方法是定义一个函数,该函数进行检查并 returns 所需键处的内容(如果存在),例如:

function arr(array $array, $key, $defaultValue=false) {
    return isset($arrray[$key]) ? $array[$key] : $defaultValue            
}

您为调用函数付出了少量的性能损失(您可以通过删除 $array 参数的类型提示来减少它),但是您有更稳定的代码。

您的使用示例:

if(arr($_POST, 'somedata') === 2)) {
    // do your stuff
}