为变量提供默认值的最佳方法(模拟 Perl | | ,| | =)

我喜欢在佩尔做这样的事情: 如果 $bar是空的或者没有定义的,就把 $baz赋值给 $foo。您还有 $foo ||= $bletch,它将只分配 $bletch$foo,如果 $foo没有定义或空。

在这种情况下,三元操作符是乏味和令人厌烦的。在 PHP 中肯定有一个简单、优雅的方法可用吧?

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

110876 次浏览

PHP 5.3有一个简写的 ?:运算符:

$foo = $bar ?: $baz;

如果 $bar不是空值(我不知道这在 PHP 和 Perl 中会有什么不同) ,那么就会赋 $bar,否则就会赋 $baz,在 Perl 和更老版本的 PHP 中也是如此:

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

但是 PHP 没有这样的复合赋值操作符(也就是说,没有相当于 Perl 的 ||=)。

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

与旧版 PHP 保持兼容的一个常见习惯做法是:

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

这适用于可以在布尔上下文中计算的值。这里的优点是,如果变量未定义,它还会给出调试通知。

谢谢你的回答!

对于其他来这里寻找可能的替代方案的人来说,这里有一些功能可以帮助他们摆脱这种单调乏味的工作。

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);

我相信这些还可以改进。

在 PHP7中,我们最终找到了一种优雅地实现这一点的方法。它被称为 空结合运算符。你可以这样使用它:

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

这相当于

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

在7.* 之前的 PHP 中,可以使用? : 表示一个未定义的变量,它的错误在本地被 @抑制:

$foo = @$bar ?: $baz;

这是另一个良好的格式为 isset的情况下

isset($foo) || $foo= $bar;

另一个简单的方法,并将给你更多的控制,因为你可以添加更多的条件,并指派给另一个变量在同一时间

$foo = (isset($oData['foo']))?$bar['foo']:'default value';

一个可能的解决方案: defaultFor ()

除非我们有一个工厂解决方案(这确实非常烦人) ,否则我建议使用以下小助手。在大多数情况下,它起到了这样的作用:


function defaultFor(&$x,$default=null) {
if(!isset($x)) $x = $default;
}


//--------------------  Now you can do this: --------------


defaultFor($a,"Jack");  // if $a is not set, it will be "Jack"
defaultFor($x);         // no more notices for $x but keep it !isset


我希望这和你想达到的目标很接近。如果您将它与一个不存在的变量一起使用,它将不会给您任何通知,而且它非常方便。当然它有一个缺点: 默认值总是事先计算好的,所以不要把它作为第二个参数使用,比如 file _ get _ content 或其他参数。在这种情况下,您最好使用 isset。

我认为一般来说,做这样的事情:

$foo = $bar || $baz;

是一个坏主意,除非 $bar$baz都是布尔值。如果它们不是:

$bar = 10;
$baz = 11;

那么问题就变成了: 是什么决定了某事是真是假?大多数人可能认为零是错误的,其他的都是正确的。但是对于某些语言(例如 Ruby) ,只有 falsenil是假的,这意味着 01都是真的。由于这种跨语言的歧义,我认为在这些情况下最好是明确的:

if ($bar !== 0) {
$foo = $bar;
} else {
$foo = $baz;
}

或:

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