我经常发现自己需要使用以下逻辑模式编写代码:
$foo = isset($bar) ? $bar : $baz;
我知道?:
语法:
$foo = $bar ?: $baz;
......从表面上看,它似乎正是我所寻找的;但是,如果未设置$bar
,它会抛出一个未定义的通知索引。它也使用与empty()
相同的逻辑,这意味着FALSE
,0
,"0"
等“空”值不会通过。因此,它并不是真正的等价物。
如果没有设置$bar
,是否有更短的方式编写代码而不会发出通知?
修改
为了让它更清晰为什么我正在寻找一种快捷语法,这里有一个更好的例子:
$name = isset($employee->getName())
? $employee->getName()
: '<unknown>';
在这种情况下,$employee
可能是第三方库中的对象,而name
可能是NULL
的有效方案可能是{1}}。我想将变量$name
设置为返回的名称(如果有的话),但如果没有,则设置一些合理的默认值。
如果方法调用比getter更复杂,那么这个例子变得更加冗长,因为我们必须缓存结果:
$bar = $some->reallyExpensiveOperation();
$foo = isset($bar) ? $bar : $baz;
答案 0 :(得分:3)
当您明确预定义变量或使用带魔法吸气剂的对象时,我只会使用简写三元语法。这是我通常使用短手三元语法
的一个非常基本的例子class Foo {
public function __get($name) {
return isset($this->{$name}) ? $this->{$name} : '';
}
}
$foo = new Foo();
$bar = $foo->baz ?: 'default';
答案 1 :(得分:0)
使用error control operator,您可以在技术上将其缩短为:
$foo = @$bar ?: $baz;
如果未设置$bar
,则值的计算结果为null,并且由于您抑制了错误,因此没有错误通知。但是,有些人可能不赞同使用此代码,因为它使用@
并不好用,因为它会掩盖错误并使调试更加困难。
如果没有这个,我不相信只使用isset
会有一个较短的符号。
编辑:正如@drrcknlsn所说,如果变量是false
,0
,甚至是null
,这将不起作用,所以在我看来,没有避免调用isset
。
答案 2 :(得分:0)
如果未定义$bar
,则不会更短&#34;更短的&#34;编写相同代码的方法。
有两个,我会考虑什么&#34; hacks&#34;然而,要做到这一点,它们也可能影响其他事情:
@
进行错误限制,例如$foo = @$bar ?: $baz;
会
完全按照自己的意愿行事并限制未定义的错误
$bar
未定义时抛出。如果已定义,它也将起作用
如预期的。然而,缺点是@
会降低效率
在你的代码中,如果反复使用它。error_reporting(E_ALL & ~E_NOTICE);
。这仍将显示全部
常规错误,但不是通知,这将有效隐藏
&#34;变量未定义&#34;错误。这样做的缺点是你
不会看到任何其他通知。现在,我的强制性个人意见,我建议继续全力以赴。三元运算符已经是速记,有效地减少了以下内容:
if (isset($bar)) {
$foo = $bar;
} else {
$foo = $baz;
}
进入更短的
$foo = isset($bar) ? $bar : $baz;
并且它真的不需要花费更多的精力来编写完整的三元与较短的三元(当然,除非你的变量名称非常长)。此外,复合三元操作(即 - 一个中的几个三元组)将导致超速简化无法使用;因此,短期储蓄在编程上/道德上并不令人满意(在我看来)。
更新:为了支持您的编辑,您可以将$bar
分配给某个功能的返回值,然后$foo
根据它进行分配 - 您可以将语句组合成单行,如:
$foo = (($bar = $some->reallyExpensiveOperation()) != null) ? $bar : $baz;
这与两条线的代码长度几乎相同,但也可以从这里略微缩短。例如,如果null
不是您考虑的唯一值&#34;无效&#34;,但false
也会计算,则可以完全删除!= null
部分并允许将条件视为一个简单的布尔值:
$foo = ($bar = $some->reallExpensiveOperation()) ? $bar : $baz;
在这个例子中,$bar
在三元操作之后仍然可以访问(即 - 它不会失去范围),所以除非你需要对变量进行预处理,否则不会出现这种情况。除了可读性之外,这种方法的重大缺点。