【问题标题】:How to avoid undefined index warning for chains of 'default' values?如何避免“默认”值链的未定义索引警告?
【发布时间】:2016-02-19 17:43:37
【问题描述】:

假设我想检查几个不同的参数,然后回退到默认值,有没有办法做到这一点,而不会写出丑陋和冗长的 isset()

例如在 JS 中我们可以这样做:

var someVariable = otherVar || anotherVar || 'fallback here';

PHP 中的等价物是这样的:

$someVariable = (isset($otherVar) ? $otherVar : (isset($anotherVar) ? $anotherVar : 'fallback here'));

这显然是一团糟,难以阅读。

对于单个后备,存在很多解决方案,即:

$someVariable = $otherVar ?: 'fallback here';

但这并不能帮助我在检查中要求不止一个。

鉴于我只对值是设置还是真值感兴趣(即,我很高兴 1 被接受为使用的值,并且 0/false/null 被跳过并等待下一个要使用的链中的参数),避免未定义索引警告的最佳方法是什么?

实际上,我会在大多数 情况下对数组执行此操作,但不是全部,而且它们可能是不同的数组。我可能想首先使用 $_POST,然后在不同的键下检查 $_GET,然后回退到例如默认字符串。

【问题讨论】:

  • 我曾经做过error_reporting(0);警告消失..
  • 我使用 error_reporting 来检查其他问题,所以我不想关闭它。
  • 我也不想压制 E_NOTICE,因为如果可能的话,我想从根本上解决问题,而不是仅仅忽略它的报告。

标签: php


【解决方案1】:

忽略 PHP 警告和通知根本不是一个好主意。
但只是为了实验,我可以建议你错误控制操作员@
PHP 支持一种错误控制运算符:at 符号 (@)。当附加到 PHP 中的表达式时,该表达式可能生成的任何错误消息都将被忽略。

$someVariable = @$otherVar ? @$var : 'fallback here';
echo $someVariable;
// output: fallback here

http://php.net/manual/en/language.operators.errorcontrol.php

【讨论】:

  • 我不知道@运算符可以在使用变量之前使用;这真的很有趣,可能是一个很好的解决方案..
  • 我发现这在数组的情况下没有帮助 - 例如:$animals = array(); $my_animal = @$animals['dog'] ? $animals['dog'] : 'Some dog name'; 这仍然会为我抛出未定义的索引警告 - 有什么方法可以解决你所知道的?替代方案要冗长得多,我真的不喜欢它,并且需要一个月的星期天时间才能将其改装到我的代码中!:if(isset($animals) && isset($animals['dog'])) { $my_animal = $animals['dog']; } else { $my_animal = 'Some dog name'; }
【解决方案2】:

您可以将?: 链接起来,但您仍然需要将suppress errors@ 链接起来。

例如,以下将与您的 JavaScript 示例类似:

$foo = @$bar ?: @$baz ?: @$qux ?: "I give up";

相当于多个“单一后备”:

$foo = (@$bar ?: (@$baz ?: (@$qux ?: "I give up")));

不过要小心,?: 只检查真实性。在某些情况下isset() 和真实性do not agree。此外,?: 后备功能已在 PHP 5.3 中引入。

如果您只关心 null 并且有 PHP 7 可用,它引入了 null coalescing operator

【讨论】:

  • 这很好;真实性并不能完全发挥作用,因为它会拒绝例如明确提供的布尔假值。我喜欢这种风格,因为它简单明了,所以很遗憾,它不起作用!
【解决方案3】:

这是模棱两可的,它已被弃用......

$something = $a ? $b : $c ?: $d;

因此,您有 2 种分组方式:

$something = $a ? $b : ($c ?: $d); // version 1
$something = ($a ? $b : $c) ?: $d; // version 2

哪一个是正确的?让我们测试一下...

$posibilities = [TRUE, FALSE, NULL, [], new stdClass()];
$v1_is_correct = TRUE;
$v2_is_correct = TRUE;

foreach ($posibilities as $a) {
  foreach ($posibilities as $b) {
    foreach ($posibilities as $c) {
      foreach ($posibilities as $d) {

        $original = (int)($a ? $b : $c ?: $d);
        $v1 = (int)($a ? $b : ($c ?: $d));
        $v2 = (int)(($a ? $b : $c) ?: $d);

        $v1_is_correct = $v1_is_correct && ($original === $v1);
        $v2_is_correct = $v2_is_correct && ($original === $v2);

        print "ORIG: $original - V1: $v1 - V2: $v2 \n";
      }
    }
  }
}

print "\n";
$v1_is_correct ? print "V1 is correct \n" : NULL;
$v2_is_correct ? print "V2 is correct \n" : NULL;

结果: V2 是正确的。

$a ? $b : $c ?: $d 

相当于...

($a ? $b : $c) ?: $d

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-03
    • 2010-11-14
    相关资源
    最近更新 更多