是否有更好的PHP方式从数组(字典)的键获取默认值


Is there a better PHP way for getting default value by key from array (dictionary)?

Python中可以这样做:

foo = {}
assert foo.get('bar', 'baz') == 'baz'

PHP中可以使用三元运算符,如:

$foo = array();
assert( (isset($foo['bar'])) ? $foo['bar'] : 'baz' == 'baz' );

我正在寻找一个高尔夫版本。我能用PHP做得更短/更好吗?

UPDATE [March 2020]:

assert($foo['bar'] ?? 'baz' == 'baz');

看来Null coalescing operator ??今天值得一看。

在下面的注释中找到(+1)

时间在流逝,PHP在不断发展。PHP 7现在支持空合并操作符??:

// Fetches the value of $_GET['user'] and returns 'nobody'
// if it does not exist.
$username = $_GET['user'] ?? 'nobody';
// This is equivalent to:
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
// Coalescing can be chained: this will return the first
// defined value out of $_GET['user'], $_POST['user'], and
// 'nobody'.
$username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';

我想出了这个小的辅助函数:

function get(&$var, $default=null) {
    return isset($var) ? $var : $default;
}

不仅适用于字典,还适用于所有类型的变量:

$test = array('foo'=>'bar');
get($test['foo'],'nope'); // bar
get($test['baz'],'nope'); // nope
get($test['spam']['eggs'],'nope'); // nope
get($undefined,'nope'); // nope

每次引用传递之前未定义的变量不会导致NOTICE错误。相反,通过引用传递$var将定义它并将其设置为null如果传递的变量是null,也将返回默认值。还要注意垃圾邮件/鸡蛋示例中隐式生成的数组:

json_encode($test); // {"foo":"bar","baz":null,"spam":{"eggs":null}}
$undefined===null; // true (got defined by passing it to get)
isset($undefined) // false
get($undefined,'nope'); // nope

注意,尽管$var是通过引用传递的,但get($var)的结果将是$var的副本,而不是引用。我希望这对你有帮助!

使用错误控制操作符@与PHP 5.3的快捷版本的三元操作符:

$bar = @$foo['bar'] ?: 'defaultvalue';

我发现创建这样一个函数很有用:

function array_value($array, $key, $default_value = null) {
    return is_array($array) && array_key_exists($key, $array) ? $array[$key] : $default_value;
}

并像这样使用:

$params = array('code' => 7777, 'name' => "Cloud Strife"); 
$code    = array_value($params, 'code');
$name    = array_value($params, 'name');
$weapon  = array_value($params, 'weapon', "Buster Sword");
$materia = array_value($params, 'materia');
echo "{ code: $code, name: $name, weapon: $weapon, materia: $materia }";

在这种情况下,默认值是null,但您可以将其设置为您需要的任何值。

PHP 5.3有一个快捷版本的三元操作符:

$x = $foo ?: 'defaultvaluehere';

也就是

if (isset($foo)) {
   $x = $foo;
else {
   $x = 'defaultvaluehere';
}

否则,没有更短的方法

这是一种"略"的hack方法:

<?php
    $foo = array();
    var_dump('baz' == $tmp = &$foo['bar']);
    $foo['bar'] = 'baz';
    var_dump('baz' == $tmp = &$foo['bar']);

http://codepad.viper - 7. - com/flxhch

显然这不是一个好的方法。但它在其他情况下很方便。例如,我经常这样声明GET和POST变量的快捷方式:

<?php
    $name =& $_GET['name'];
    // instead of
    $name = isset($_GET['name']) ? $_GET['name'] : null;
PS:可以称之为"内置==$_=&特殊比较运算符":
<?php
    var_dump('baz' ==$_=& $foo['bar']);

PPS:显然你可以直接用

<?php
    var_dump('baz' == @$foo['bar']);

,但这比==$_=&操作符更糟糕。你知道,人们不太喜欢错误抑制操作符

如果您在数组中按键枚举默认值,则可以这样做:

$foo = array('a' => 1, 'b' => 2);
$defaults = array('b' => 55, 'c' => 44);
$foo = array_merge($defaults, $foo);
print_r($foo);

结果是:

Array
(
    [b] => 2
    [c] => 44
    [a] => 1
)

枚举默认值的键/值对越多,代码就越好。

"Marc B"提出了一个使用三元快捷键$x = $foo ?: 'defaultvaluehere';的解决方案,但它仍然给出通知。可能是打错了,也许他的意思是??或者是在PHP 7发布之前编写的。根据三元描述:

从PHP 5.3开始,可以省略三元操作符的中间部分。表达式expr1 ?: expr3如果expr1的结果是TRUE,则返回expr1,否则返回expr3

但是它没有在里面使用isset并且产生通知。为了避免注意,最好使用空合并运算符 ?? ,它在其内部使用isset。在PHP 7中可用。

表达式(expr1) ??如果expr1为NULL, (expr2)的计算结果为expr2,否则为expr1。特别是,如果左边的值不存在,这个操作符不会发出通知,就像isset()一样。这对于数组键尤其有用。

示例#5分配默认值

<?php
// Example usage for: Null Coalesce Operator
$action = $_POST['action'] ?? 'default';
// The above is identical to this if/else statement
if (isset($_POST['action'])) {
    $action = $_POST['action'];
} else {
    $action = 'default';
}
?>