2011-05-12 137 views
75

我喜欢在Perl中做这样的事情:$foo = $bar || $baz$baz设置为$foo如果$bar为空或未定义。您还有$foo ||= $bletch,如果$foo未定义或为空,则只会将$bletch指定给$foo为变量赋予默认值的最佳方式(模拟Perl ||,|| =)

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

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

+0

有关[Codereview。SE]:http://codereview.stackexchange.com/q/12722/31433 – Palec 2015-08-08 01:28:41

+1

顺便说一句,具有所需功能的Perl运算符是'//'和'// =',它们自Perl v5.10.0起存在。最初的'||'和'|| ='测试逻辑值,而不是定义。 – Palec 2015-08-08 01:33:14

+0

@Palec,为什么要将一个有29个upvotes的4年老问题确定为6个upvotes(其本身被标记为另一个问题的副本)的1年期问题的副本?我认为这有很大的价值这个问题,因为标题更通用(不引用答案,即:isset())。 – 2015-08-10 17:24:39

回答

154

PHP 5.3有个缩写?:操作:

$foo = $bar ?: $baz; 

哪个分配$bar如果它不是空值(我不知道如何做到这一点在PHP Perl的不同),否则$baz,并与此相同的Perl和旧版本的PHP:

$foo = $bar ? $bar : $baz; 

但PHP不具有这样的复合赋值操作符(也就是没有Perl的||=的当量)。

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

+2

+1为了向我介绍5​​.3的另一个强大功能,我错过了RHEL5/PHP5.1.2服务器。 – 2011-05-12 02:10:54

+0

我想你的意思是在倒数第二句中,“第一个返回”而不是“第二个”。 – Toto 2011-05-12 08:16:56

+12

请注意,如果您的变量未定义,PHP将会发出通知。很遗憾,这不是'$ var = isset($ var)的替代品吗? $ var:'默认值';'它说在答案中...只是指出任何撇弃它的人。 :-D – Brad 2014-06-02 15:00:00

7

一个常见成语留在旧的PHP版本兼容是:

$var = $bool or $var = "default"; 
// If I use it, then only with excessive spaces for clarity. 

这适用于可以在布尔上下文中的评估值。这里的优点是它也给你说调试e_notice如果变量是未定义的。

+0

是不是用'$ bool? $ bool:“default”'如果'$ bool'未定义? – BoltClock 2011-05-12 02:03:10

+0

当然,这是一样的。我认为OP是指'isset($ var)? $ var:DEFAULT'。但无论如何,他听起来像是想避开它们。 – mario 2011-05-12 02:05:46

7

感谢您的所有伟大的答案!

对于任何人来这里寻找可能的替代方案,这里有一些功能可以帮助缓解这类事情。

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]; 
    } 
} 

例子:

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

//$foo = $baz || $bletch 
$foo = select_defined($baz, $bletch); 

我敢肯定,这可以改进。

50

在PHP 7中,我们终于有办法优雅地做到这一点。它被称为Null coalescing operator。您可以使用它像这样:

$name = $_GET['name'] ?? 'john doe'; 

这相当于

$name = isset($_GET['name']) ? $_GET['name']:'john doe'; 
+7

为了让操作员使用最令人讨厌,最酷的名字, – 2016-04-22 19:17:20

+5

我认为[飞船运营商](http://php.net/manual/en/migration70.new-features.php#migration70.new-features.spaceship-op)也有优点。 – Mariano 2017-06-11 05:41:55

1

在PHP中早于7 *,可以使用:用于与@局部地抑制未定义具有可变错误:

$foo = @$bar ?: $baz;