给变量赋值的最佳方法(模拟Perl ||,|| =)

Tom*_*ger 117 php perl operators default-value

我喜欢在Perl中做这种事情:$foo = $bar || $baz分配$baz$fooif $bar是空的还是未定义的.您还可以$foo ||= $bletch将只分配$bletch$foo如果$foo没有定义或为空.

在这种情况下,三元运算符是乏味和乏味的.当然,PHP中有一个简单,优雅的方法?

或者是使用isset()的自定义函数的唯一答案?

Bol*_*ock 204

PHP 5.3有一个速记?:运算符:

$foo = $bar ?: $baz;
Run Code Online (Sandbox Code Playgroud)

$bar如果它不是一个空值,我会分配(我不知道PHP与Perl的不同之处),否则$baz,与Perl和旧版本的PHP中的相同:

$foo = $bar ? $bar : $baz;
Run Code Online (Sandbox Code Playgroud)

但PHP没有这个复合赋值运算符(也就是说,没有Perl的等价物||=).

此外,如果$bar未设置,PHP将发出噪音,除非您关闭通知.isset()和之间也存在语义差异empty().如果变量不存在,则前者返回false,或者设置为NULL.后者返回true,如果它不存在,或者设置为0,'',falseNULL.

  • 请注意,如果您的变量未定义,PHP将发出有关它的通知.不幸的是,这不能替代`$ var = isset($ var)?$ var:'默认值';`它在答案中说...只是指出它为任何撇去它的人.:-D (18认同)
  • 做$ var = @ $ var?:'默认值'是不好的; 如果是这样,为什么?鉴于唯一的"错误"可能是$ var未设置,并且我们不关心$ var是否未设置... (5认同)
  • +1为了向我介绍5​​.3的另一个重要功能,我在RHEL5/PHP5.1.2服务器中错过了. (2认同)

jps*_*der 102

在PHP 7中,我们终于有办法优雅地完成这项工作.它被称为Null合并运算符.你可以像这样使用它:

$name = $_GET['name'] ?? 'john doe';
Run Code Online (Sandbox Code Playgroud)

这相当于

$name = isset($_GET['name']) ? $_GET['name']:'john doe';
Run Code Online (Sandbox Code Playgroud)

  • 我认为[宇宙飞船运营商](http://php.net/manual/en/migration70.new-features.php#migration70.new-features.spaceship-op)也有其优点. (13认同)
  • 我以为Mariano会拉我们的腿,但不会,这是`<=>`的事情,启动起来非常准确! (3认同)
  • 请注意,空合并运算符的行为与条件运算符不同,因为它特定于“null”值。例如,如果`$_GET['name']`设置为空字符串,第一行将返回空字符串,但我们可以使用`$_GET['name']返回“john doe”?$_GET['name'] : '约翰·多伊'`。 (2认同)

Tom*_*ger 8

感谢所有伟大的答案!

对于其他任何人来到这里寻找可能的替代方案,这里有一些功能可以帮助你解决这类问题.

function set_if_defined(&$var, $test){
    if (isset($test)){
        $var = $test;
        return true;
    } else {
        return false;
    }
}

function set_unless_defined(&$var, $default_var){
    if (! isset($var)){
        $var = $default_var;
        return true;
    } else {
        return false;
    }
}

function select_defined(){
    $l = func_num_args();
    $a = func_get_args();
    for ($i=0; $i<$l; $i++){
        if ($a[$i]) return $a[$i];
    }
}
Run Code Online (Sandbox Code Playgroud)

例子:

// $foo ||= $bar;
set_unless_defined($foo, $bar);

//$foo = $baz || $bletch
$foo = select_defined($baz, $bletch);
Run Code Online (Sandbox Code Playgroud)

我相信这些可以改进.


mar*_*rio 7

与旧版本PHP兼容的常用习惯是:

 $var = $bool   or   $var = "default";
 // If I use it, then only with excessive spaces for clarity.
Run Code Online (Sandbox Code Playgroud)

这适用于可以在布尔上下文中计算的值.这里的优点是,如果变量未定义,它还会为您提供调试e_notice.


And*_*kov 5

在7. *之前的PHP中,对于未定义的变量,可以使用?:,该变量在本地用-抑制了错误@

$foo = @$bar ?: $baz;
Run Code Online (Sandbox Code Playgroud)

  • 7.* 之后的版本会发生什么? (2认同)