如果键不存在,是否有默认的数组值?

56

如果我有一个包含信息的数组,是否有任何方法可以为不存在的键设置默认值以返回?

function items() {
    return array(
        'one' => array(
              'a' => 1,
              'b' => 2,
              'c' => 3,
              'd' => 4,
         ),
         'two' => array(
              'a' => 1,
              'b' => 2,
              'c' => 3,
              'd' => 4,
         ),
         'three' => array(
              'a' => 1,
              'b' => 2,
              'c' => 3,
              'd' => 4,
         ),
    );
}

在我的代码中

$items = items();
echo $items['one']['a']; // 1

但是,如果我提供了一个不存在的键,是否可以返回默认值呢?

$items = items();
echo $items['four']['a']; // DOESN'T EXIST RETURN DEFAULT OF 99

1
http://php.net/array_key_exists。该手册非常有用。 - vascowhite
3
虽然使用array_key_exists可以达到效果,但对于大型数组或需要大量检查的情况可能会导致性能问题。array_key_exists需要遍历整个数组以确保键存在。相比之下,isset()只需要一次检查就可以继续执行。 - CaseySoftware
4
PHP需要的是一个数组合并函数,它可以检查元素是否存在并获取其值,如果为空,则返回默认值。 - Jens
11个回答

89
我知道这是一个旧问题,但我的谷歌搜索“php数组默认值”将我带到了这里,我想发表我正在寻找的解决方案,很有可能会帮助其他人。
我想要一个带有默认选项值的数组,可以被自定义值覆盖。我最终使用了array_merge
示例:
<?php
    $defaultOptions = array("color" => "red", "size" => 5, "text" => "Default text");
    $customOptions = array("color" => "blue", "text" => "Custom text");
    $options = array_merge($defaultOptions, $customOptions);
    print_r($options);
?>

输出:

Array
(
    [color] => blue
    [size] => 5
    [text] => Custom text
)

85

从 PHP 7 开始,有一个新的运算符专门为这些情况设计,称为Null Coalesce Operator

现在你可以这样做:

echo $items['four']['a'] ?? 99;

替代

echo isset($items['four']['a']) ? $items['four']['a'] : 99;

在 PHP 7 之前还有另一种方法来实现这个:

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

以下内容将不会出现问题:

echo get($item['four']['a'], 99);
echo get($item['five'], ['a' => 1]);

请注意,使用此方法,在非数组值上调用数组属性将会抛出错误。例如:

echo get($item['one']['a']['b'], 99);
// Throws: PHP warning:  Cannot use a scalar value as an array on line 1

此外,有一种情况会抛出致命错误:

$a = "a";
echo get($a[0], "b");
// Throws: PHP Fatal error:  Only variables can be passed by reference

最后,有一个丑陋的解决方法,但几乎可以很好地工作(如下所述,在某些情况下存在问题):

function get($value, $default = null)
{
    return isset($value) ? $value : $default;
}
$a = [
    'a' => 'b',
    'b' => 2
];
echo get(@$a['a'], 'c');      // prints 'c'  -- OK
echo get(@$a['c'], 'd');      // prints 'd'  -- OK
echo get(@$a['a'][0], 'c');   // prints 'b'  -- OK (but also maybe wrong - it depends)
echo get(@$a['a'][1], 'c');   // prints NULL -- NOT OK
echo get(@$a['a']['f'], 'c'); // prints 'b'  -- NOT OK
echo get(@$a['c'], 'd');      // prints 'd'  -- OK
echo get(@$a['c']['a'], 'd'); // prints 'd'  -- OK
echo get(@$a['b'][0], 'c');   // prints 'c'  -- OK
echo get(@$a['b']['f'], 'c'); // prints 'c'  -- OK
echo get(@$b, 'c');           // prints 'c'  -- OK

1
在你的示例函数中,你正在丢弃默认值! - Bas van den Heuvel
1
在您的函数中,应该是 return isset($value) ? $value : $default; - Mohamed Gharib

21

这应该能解决问题:

$value =  isset($items['four']['a']) ? $items['four']['a'] : 99;

如果您需要经常编写这些代码,那么编写一个辅助函数会很有用:

function arr_get($array, $key, $default = null){
    return isset($array[$key]) ? $array[$key] : $default;
}

44
我无法相信现在已经是2013年了,却没有原生的函数来处理这个。打两遍整个表达式有什么意义呢? - Jens
1
Kohana有一个数组助手,你可以通过调用Arr::get('key', $array, $default)来使用它,非常方便。 - Mārtiņš Briedis
31
我希望我能对PHP本身进行踩票,因为它没有更好的处理这个问题的方式。 - Tyler Collier
4
是的,很难相信 PHP 没有像这样的东西:$array->get($key, $default) - fe_lix_
4
我认为你应该使用array_key_exists而不是isset进行测试,因为将键设置为null值仍应视为已设置。 - Elmar Zander
显示剩余3条评论

9

自PHP7.0版本起,您可以使用空合并运算符??

$value = $items['one']['two'] ?? 'defaut';

对于小于5.6的版本

您也可以这样做:

$value =  $items['four']['a'] ?: 99;

这相当于:

$value =  $items['four']['a'] ? $items['four']['a'] : 99;

它可以避免将整个语句包装到函数中!

请注意,如果在items['four']中未设置键'a',则此代码并非仅返回99。相反,它仅在值$items['four']['a']为false(未设置或为假值,如0)时才返回99。


你真的确定这两行代码是一样的吗? - Mārtiņš Briedis
这不会返回值$items['four']['a'],而是会返回TRUE。 - Weboide
你是对的...对此我很抱歉。如果你去掉isset函数,它就可以工作了。现在正在编辑。 - Eric Keyte
7
这将检查$items['four']['a']的值而不是其存在性。这与使用isset检查非常不同。 - fe_lix_
2
如果$items['four']['a']的值为0FALSE,会发生什么? - Shankar Prakash G
1
在 PHP7 中,您可以这样做: $value = $items['four']['a'] ?? 99; - Bikal Basnet

4

这个问题非常古老,但是也许我的解决方案仍然有用。对于我经常需要使用“if array_key_exists”的项目,比如Json解析,我开发了以下函数:

function getArrayVal($arr, $path=null, $default=null) {
    if(is_null($path)) return $arr;
    $t=&$arr;
    foreach(explode('/', trim($path,'/')) As $p) {
        if(!array_key_exists($p,$t)) return $default;
        $t=&$t[$p];
    }
    return $t;
}

您可以简单地像这样“查询”数组:
$res = getArrayVal($myArray,'companies/128/address/street');

相较于传统的方式,这种方式更易读...

$res = (isset($myArray['companies'][128]['address']['street']) ? $myArray['companies'][128]['address']['street'] : null);

3

据我所知没有。

您需要单独使用isset检查。

echo isset($items['four']['a']) ? $items['four']['a'] : 99;

2
使用Array_Fill()函数 http://php.net/manual/en/function.array-fill.php
$default = array(
              'a' => 1,
              'b' => 2,
              'c' => 3,
              'd' => 4,
         );
$arr = Array_Fill(1,3,$default);
print_r($arr);

这是结果:

Array
(
    [1] => Array
        (
            [a] => 1
            [b] => 2
            [c] => 3
            [d] => 4
        )

    [2] => Array
        (
            [a] => 1
            [b] => 2
            [c] => 3
            [d] => 4
        )

    [3] => Array
        (
            [a] => 1
            [b] => 2
            [c] => 3
            [d] => 4
        )

)

0

我不知道如何使用您提供的代码精确地实现它,但是您可以通过编写一个接受任意数量参数并返回您要查找的参数或默认值的函数来解决问题。

用法:

echo arr_value($items, 'four', 'a');

或者:

echo arr_value($items, 'four', 'a', '1', '5');

功能:

function arr_value($arr, $dimension1, $dimension2, ...)
{
    $default_value = 99;
    if (func_num_args() > 1)
    {
        $output = $arr;
        $args = func_gets_args();
        for($i = 1; $i < func_num_args(); $i++)
        {
            $outout = isset($output[$args[$i]]) ? $output[$args[$i]] : $default_value;
        }
    }
    else
    {
        return $default_value;
    }

    return $output;
}

0

你可以使用DefaultArray来自非标准PHP库。你可以从你的项目中创建新的DefaultArray:

use function \nspl\ds\defaultarray;
$items = defaultarray(function() { return defaultarray(99); }, $items);

或者从items()函数返回DefaultArray:

function items() {
    return defaultarray(function() { return defaultarray(99); }, array(
        'one' => array(
              'a' => 1,
              'b' => 2,
              'c' => 3,
              'd' => 4,
         ),
         'two' => array(
              'a' => 1,
              'b' => 2,
              'c' => 3,
              'd' => 4,
         ),
         'three' => array(
              'a' => 1,
              'b' => 2,
              'c' => 3,
              'd' => 4,
         ),
    ));
}

请注意,我们使用匿名函数 function() { return defaultarray(99); } 创建嵌套的默认数组。否则,默认数组对象的相同实例将在所有父数组字段之间共享。该内容与编程有关。

0

目前使用的是 PHP 7.2

>>> $a = ["cat_name"=>"Beverage", "details"=>"coca cola"];
=> [
     "cat_name" => "Beverage",
     "details" => "coca cola",
   ]
>>> $a['price']
PHP Notice:  Undefined index: price in Psy Shell code on line 1
=> null
>>> $a['price'] ?? null ? "It has price key" : "It does not have price key"
=> "It does not have price key"

这个古老的问题已经有几个详细的答案了。如果您认为您的答案比他们的更有价值,请详细说明,而不是仅提供一小段代码片段。 - gilliduck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接