【问题标题】:Is @$array['possibly_missing_key'] an anti-pattern?@$array['possibly_missing_key'] 是反模式吗?
【发布时间】:2011-05-25 09:36:41
【问题描述】:

从 PHP 数组中提取可能缺失的值时可以使用 @ 吗?示例:

$value = @$array['possibly_missing_key'];

预期行为:

if (isset($array['possibly_missing_key'])) {
    $value = $array['possibly_missing_key'];
} else {
    $value = null;
}

我想知道,在传播使用模式之前。

【问题讨论】:

  • 我是唯一一个使用array_key_exists 而不是 isset 的人吗?
  • (旁注) isset 未检测到可能丢失的密钥。为此使用array_key_exists。试试$arr = array('notMissing' => NULL);isset
  • @AlexV @Gordon:我认为这并不重要,因为默认值无论如何都是 NULL :P
  • @AlexV - 可能是微优化,我知道,但我发现 isset() 比 array_key_exists() 快...可能是因为它是一种语言构造而不是函数(所有相关函数调用开销)
  • 我和@AlexV 一起讨论这个问题。缺少的键和值为NULL的现有键之间存在语义差异

标签: php arrays operators error-suppression


【解决方案1】:

实际上isset 变体是反模式。如果您只是使用isset($var)?$var:NULL 来抑制“错误”,那么您除了使用正确的语法来抑制错误之外一无所获。它具有相同的结果,但可读性较差。

人们为此争论不休,因为感知到的“清洁度”以及使用 isset 是一种微优化。避免 @ 并使用 isset 作为语法盐替换只是货物崇拜编程。

【讨论】:

  • 感谢您提出逆向观点。
  • @IvoDanihelka:其实我想撤退,加个大全看。没有一个模式可以匹配所有用例。对 isset/@ 保持灵活而不是虔诚,使用手头工作的最佳工具。
【解决方案2】:

@ 运算符抑制错误消息,并潜在地使用它为您的代码设置其他错误和最终难以追踪的意外行为。因此,它肯定是一种反模式。

因此,我更喜欢第二位。更清楚了

  • 它可能不存在于数组中,并且
  • 如果不存在默认值是什么

为了更简洁,您可以使用三元条件运算符?:,如Mark Baker's answer 所示。代码略少,符号多,但含义很好理解。

【讨论】:

  • 我明白了。安全的@用法可能会误导其他开发人员在错误的地方使用它。
【解决方案3】:

第二个代码块(或 Mark Ba​​ker 的替代代码,其工作方式完全相同)更好。我不完全确定 PHP,但在许多其他编程语言中,简单地忽略变量几乎肯定会引发错误。至少在第二个块中,您将变量初始化为某个值或内存位置。

如果您希望函数在最终产品中抛出预期的错误,则应该更常用地使用错误抑制(但是,很多时候情况并非如此)。

祝你好运!
丹尼斯 M.

【讨论】:

    【解决方案4】:

    第三个选项:

    $value = (isset($array['key']) ? $array['key'] : null);
    

    我知道这并不能直接回答问题;我会把它作为评论,除非它确实需要格式化。

    这里的想法是,如果您试图通过使用单行而不是 if-else 块来缩短代码,那么您仍然可以使用三元运算符将其变成简洁的单行,给出你是两全其美。

    【讨论】:

    • 这不是真正的第三个选项,这是选项 2 的不同格式(因为它在功能上相同)。你会说if (x) { something }if (!x) {} else { something } 是两个不同的解决方案,因为它们的写法不同吗?
    • @Piskvor - 嗯,这有点挑剔。这是不同的语法,所以我会说是的,这是第三种选择,即使它实际上与他的原始代码相同。但我的观点是提供一种不使用@ 的单线方法,因为这似乎是他的问题所在。
    • 好吧,我对此持怀疑态度。语法不同,但做同样的事情。你是对的,它不那么冗长,同时保留了功能。 (我想这更多地是关于我挑剔的冲动,而不是关于手头的问题;))
    【解决方案5】:

    忽略警告绝对是一种反模式;所以是的,这是一种反模式(我可以保证,如果你学会抑制警告,其中一个会回来咬你,如果不是更糟的话)。

    另外,虽然第二个版本更冗长,但它为未初始化的变量提供了一个已知状态(或者可以用来处理问题,如果该变量应该被填充)。

    【讨论】:

      【解决方案6】:

      或者

      $value = (isset($array['possibly_missing_key'])) ? $array['possibly_missing_key']: null;
      

      【讨论】:

      • +1 如果使用 PHP >= 5.3,您可以使用新的更短形式:isset($array['possibly_missing_key']) ?: null;
      • @webbiedave:不,这将返回isset(...) 的结果,而不是实际的数组值。
      • @webbiedave:这个简短的版本在这种情况下可以工作吗?它不会返回isset() 的值(即真或假)而不是变量本身吗?
      • 突然间,我渴望在 C# 中找到空合并运算符 (someVar ?? someDefaultValue)...
      • 哦,快!好吧,我会留下评论,这样他就可以看到更短的表格以供将来使用。
      猜你喜欢
      • 2012-06-22
      • 2018-03-27
      • 2011-08-04
      • 2010-11-04
      • 2023-03-11
      • 2011-01-28
      • 1970-01-01
      相关资源
      最近更新 更多