如果变量已设置,则分配

30

在 PHP 中,我经常会写出这样的代码:

$a = isset($the->very->long->variable[$index])
            ? $the->very->long->variable[$index]
            : null;

有没有更简单的方法来做这个?最好是不用两次写出 $the->very->long->variable[$index]


通过使用面向对象编程和使用__get和__set方法? - Ron van der Heijden
@DaHaKa:在设置良好的服务器上可能会发出警告(E_STRICT | E_ALL) - Elias Van Ootegem
如果您经常使用相同的长变量,则可以使用引用:$ref = $the->very->long->variable; $a = !empty($ref[$index]) ? $ref[$index] : null; $b = !empty($ref[++$index])...,或者如@Bondye所指出的那样,使用魔术获取器方法,并将其设置为返回null或属性值。 - Elias Van Ootegem
看起来->variable可以实现/封装到ArrayAccess,并在offsetGet操作中对未设置的索引默认返回NULL。- 还请仔细检查潜在的重复内容,你可能会在这个网站上找到一些宝贵的信息。 - hakre
可能的单子(maybe monad)可能适用于此,尽管我不太了解它是否确切可行:https://github.com/ircmaxell/monad-php - user151841
5个回答

59

更新一下,因为PHP 7已经发布并且在这个问题上有了重大改变;之前的回答是针对PHP 5的。

PHP 7解决了这个问题。因为你说的在PHP中经常写这个,但这绝不优雅。

在PHP 7中引入了Null Coalesce Operator (RFC),它完美地缩写了isset三元条件语句。

它的目的是替代这种类型的条件语句:

$var = isset($dict['optional']) ? $dict['optional'] : 'fallback';

那就是说:

$var = $dict['optional'] ?? 'fallback';
更好的是,空合并运算符可以链接使用:
$x = null;
# $y = null; (undefined)
$z = 'fallback';

# PHP 7
echo $x ?? $y ?? $z   #=> "fallback"

# PHP 5
echo isset($x) ? $x : (isset($y) ? $y : $z)

空合并运算符与isset()的作用完全相同:如果:

  • 变量已定义(存在)
  • 变量不为 null

对于PHP初学者的一个提示:如果您使用三元条件,但是您知道主题变量必定被定义(但您希望有针对假值的备选方案),那么可以使用Elvis operator

$var = $dict['optional'] ?: 'fallback';

使用Elvis运算符,如果$dict['optional']是无效的偏移量或$dict未定义,则会收到一个E_NOTICE警告(PHP 5和7)。这就是为什么在PHP 5中,人们在不确定输入时使用丑陋的isset a ? a : b形式。


做得好,@Morgan更新了一个新答案!谢谢。 - Mr Goobri

10

遗憾的是不行,因为RFC被拒绝了。同时,由于isset不是函数而是语言结构,您不能为此编写自己的函数。

注意:因为这是一个语言结构而不是函数,所以不能使用变量函数来调用。


2

如果你只是将 null 赋值给未设置的变量,可以使用以下代码:

$a = @$the->very->long->variable[$index];

@ 符号可以让该指令不产生错误。


1
假设您已经知道$the->very->long->variable已经被设置,而您只是担心数组索引的问题...
$x = $the->very->long->variable;
$a = isset($x[$index]) ? $x[$index] : null;

或者,您可以使用更通用的变量来围绕您的代码使用:

function array_valifset($arr,$k, $default=null) {
    return isset($arr[$k]) ? $arr[$k] : $default;
}

然后对于任何数组值,可以这样调用:

$a = array_valifset($the->very->long->variable,$index);

谢谢。我原本希望我只是忽略了一个内置功能。显然情况并非如此。 - oz1cz
不行。正如 @eisberg 所说,PHP开发人员明确拒绝了isset的简写解决方案。 :-( 我相信他们有他们的理由。 - SDC

-1

我偶然遇到了相同的问题并发现引用数组元素不会发出通知或警告,但会返回null(至少在PHP 5.6中)。

$foo = ['bar' => 1];

var_dump($bar = &$foo['bar']); // int 1
var_dump($baz = &$foo['baz']); // null

在if语句内部:

if($bar = &$foo['bar']) {
    echo $bar;
}
if($baz = &$foo['baz']) {
    echo $baz;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接