有没有更好的 PHP 方法从数组(字典)中通过键获取默认值?

发布于 2024-11-23 18:11:30 字数 577 浏览 2 评论 0原文

Python中可以这样做:

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

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

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

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

更新 [2020 年 3 月]:

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

空合并运算符 ?? 似乎是 值得今天查看

在下面的评论中找到(+1)

In Python one can do:

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

In PHP one can go for a trinary operator as in:

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

I am looking for a golf version. Can I do it shorter/better in PHP?

UPDATE [March 2020]:

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

It seems that Null coalescing operator ?? is worth checking out today.

found in the comments below (+1)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

逆光下的微笑 2024-11-30 18:11:30

随着时间的流逝,PHP 也在不断发展。 PHP 7 现在支持 null合并运算符??

// 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';

Time passes and PHP is evolving. PHP 7 now supports the null coalescing operator, ??:

// 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';
月下客 2024-11-30 18:11:30

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

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如果传递的变量是<代码>空。另请注意垃圾邮件/鸡蛋示例中隐式生成的数组:

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 的,不是引用。我希望这有帮助!

I just came up with this little helper function:

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

Not only does this work for dictionaries, but for all kind of variables:

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

Passing a previously undefined variable per reference doesn't cause a NOTICE error. Instead, passing $var by reference will define it and set it to null. The default value will also be returned if the passed variable is null. Also note the implicitly generated array in the spam/eggs example:

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

Note that even though $var is passed by reference, the result of get($var) will be a copy of $var, not a reference. I hope this helps!

五里雾 2024-11-30 18:11:30

使用错误控制运算符@ 使用 PHP 5.3 快捷方式版本的三元运算符:

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

Use the error control operator @ with the PHP 5.3 shortcut version of the ternary operator:

$bar = @$foo['bar'] ?: 'defaultvalue';
零度℉ 2024-11-30 18:11:30

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

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,但您可以将其设置为您需要的任何值。

我希望它有用。

I find it useful to create a function like so:

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

And use it like this:

$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 }";

The default value in this case is null, but you may set it to whatever you need.

I hope it is useful.

眸中客 2024-11-30 18:11:30

PHP 5.3 有一个三元运算符的快捷版本:

$x = $foo ?: 'defaultvaluehere';

基本上是

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

否则,不,没有更短的方法。

PHP 5.3 has a shortcut version of the ternary operator:

$x = $foo ?: 'defaultvaluehere';

which is basically

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

Otherwise, no, there's no shorter method.

安人多梦 2024-11-30 18:11:30

一种“稍微”hacky的方法:

<?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']);

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

A "slightly" hacky way to do it:

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

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

Obviously this isn't really the nice way to do it. But it is handy in other situations. E.g. I often declare shortcuts to GET and POST variables like that:

<?php
    $name =& $_GET['name'];
    // instead of
    $name = isset($_GET['name']) ? $_GET['name'] : null;

PS: One could call this the "built-in ==$_=& special comparison operator":

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

PPS: Well, you could obviously just use

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

but that's even worse than the ==$_=& operator. People don't like the error suppression operator much, you know.

假情假意假温柔 2024-11-30 18:11:30

如果您通过数组中的键枚举默认值,可以通过以下方式完成:

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

您枚举默认值的键/值对越多,代码高尔夫就变得越好。

If you enumerate the default values by key in an array, it can be done this way:

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

$foo = array_merge($defaults, $foo);

print_r($foo);

Which results in:

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

The more key/value pairs that you enumerate defaults for, the better the code-golf becomes.

美胚控场 2024-11-30 18:11:30

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

从 PHP 5.3 开始,可以省略三元运算符的中间部分。如果 expr1 计算结果为 TRUE,则表达式 expr1 ?: expr3 返回 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';
}

?>

There was a solution proposed by "Marc B" to use ternary shortcut $x = $foo ?: 'defaultvaluehere'; but it still gives notices. Probably it's a mistyping, maybe he meant ?? or it were written before PHP 7 release.
According to Ternary description:

Since PHP 5.3, it is possible to leave out the middle part of the ternary operator. Expression expr1 ?: expr3 returns expr1 if expr1 evaluates to TRUE, and expr3 otherwise.

But it doesn't use isset inside and produces notices.
To avoid notices better to use Null Coalescing Operator ?? which uses isset inside it. Available in PHP 7.

The expression (expr1) ?? (expr2) evaluates to expr2 if expr1 is NULL, and expr1 otherwise.
In particular, this operator does not emit a notice if the left-hand side value does not exist, just like isset(). This is especially useful on array keys.

Example #5 Assigning a default value

<?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';
}

?>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文