【问题标题】:Default array values if key doesn't exist?如果键不存在,则默认数组值?
【发布时间】:2012-03-22 06:46:14
【问题描述】:

如果我有一个充满信息的数组,如果键不存在,有什么方法可以默认返回值?

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

【问题讨论】:

  • php.net/array_key_exists。该手册非常有用。
  • 虽然 array_key_exists 可以工作,但它可能会导致大数组或大量检查的性能问题。它遍历整个数组以确保该键存在。或者,isset() 进行一次检查并继续前进。
  • php 需要的是一个数组合并函数,它可以检查存在并获取值或如果为空则获取默认值。

标签: php arrays default


【解决方案1】:

我知道这是一个老问题,但我在 Google 搜索“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
)

【讨论】:

    【解决方案2】:

    从 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
    

    【讨论】:

    • 在您的示例函数中,您忽略了默认值!
    • 在你的函数中,应该是return isset($value) ? $value : $default;
    【解决方案3】:

    这应该可以解决问题:

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

    辅助函数会很有用,如果你必须写很多:

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

    【讨论】:

    • 我不敢相信这是 2013 年,并且没有本机功能。将整个表达式输入两次有什么意义?
    • Kohana 有一个数组助手,你可以通过调用Arr::get('key', $array, $default) 来做到这一点,真的很方便。
    • 我希望我可以对 PHP 本身投反对票,因为它没有更好的方法来处理这个问题。
    • 是的,很难相信 PHP 没有类似的东西:$array-&gt;get($key, $default)
    • 我认为您应该使用array_key_exists 进行测试而不是使用isset,因为设置为空值的键仍应被视为已设置。
    【解决方案4】:

    从 PHP7.0 开始,您可以使用空合并运算符 ??

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

    你也可以这样做:

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

    这相当于:

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

    它省去了将整个语句包装成一个函数的需要!

    请注意,当且仅当密钥 'a' 未在 items['four'] 中设置时,这不会返回 99。相反,当且仅当值 $items['four']['a'] 为假(未设置或类似 0 的假值)时,它才返回 99。

    【讨论】:

    • 你确定这两行都一样吗?
    • 这不会返回值$items['four']['a'],而是会返回TRUE。
    • 这将检查$items['four']['a'] 的值而不是它的存在。这与使用isset检查非常不同。
    • 如果$items['four']['a']的值为0FALSE怎么办。
    • 在 php7 中你可以这样做。 $value = $items['four']['a'] ?? 99;
    【解决方案5】:

    这个问题很老了,但也许我的解决方案仍然有帮助。对于我经常需要“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);
    

    【讨论】:

      【解决方案6】:

      我不知道。

      你必须单独检查isset

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

      【讨论】:

        【解决方案7】:

        使用 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
                )
        
        )
        

        【讨论】:

          【解决方案8】:

          我不知道用你提供的代码精确地做到这一点的方法,但你可以使用一个接受任意数量参数并返回你正在寻找的参数或默认参数的函数来解决它。

          用法:

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

          【讨论】:

            【解决方案9】:

            您可以从Non-standard PHP library 使用DefaultArray。您可以从您的项目创建新的 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); } 创建嵌套默认数组。否则,默认数组对象的相同实例将在所有父数组字段之间共享。

            【讨论】:

              【解决方案10】:

              在 PHP7 中,正如 Slavik 所提到的,您可以使用空合并运算符:??

              链接到PHP docs

              【讨论】:

                【解决方案11】:

                目前使用的是 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"
                

                【讨论】:

                • 这个非常古老的问题有几个详细的答案。如果您认为您的答案增加了他们所缺乏的东西,请更详细地解释而不是只留下一个代码 sn-p。
                猜你喜欢
                • 1970-01-01
                • 2019-04-23
                • 2017-06-24
                • 2022-01-07
                • 2011-02-05
                • 1970-01-01
                • 2022-12-15
                • 2013-09-10
                • 2023-03-03
                相关资源
                最近更新 更多