【问题标题】:Nested named parameters in PHPPHP中的嵌套命名参数
【发布时间】:2011-06-17 08:08:32
【问题描述】:

命名参数非常适合 PHP 用户定义函数或类中的一长串选项。但是嵌套选项呢?

例如:

function foobar($foo,$bar,$options=array()) {

    $default_options = array('option1'=>'','option2'=>'hello','option3'=>array('option1'=>true,'option2'=>''));

    $options = array_merge($default_options,(array)$options);
}

所以选项 3 是另一个带有子选项的数组。我们是否也需要将它们放在 for 循环中以合并子选项?在这种情况下你们会怎么做?

编辑:

这是函数调用:

foobar('foo','bar',array('option1'=>'foo','option3'=>array('option1'=>false)));

$options 的结尾结构:

array(
'option1'=>'foo',
'option2'=>'hello',
'option3'=>array(
    'option1'=>false,
    'option2'=>''
);

【问题讨论】:

  • 检查array_merge(array1, array2);
  • 是的,但我已经这样做了:$options = array_merge($default_options,(array)$options);
  • 另一个选项是将每个嵌套选项数组添加为额外参数。很难在嵌套数组或使其成为位置参数的一个额外参数之间进行选择。

标签: php named-parameters multidimensional-array


【解决方案1】:

看看我在CakePHP framework找到了什么:

function merge($arr1, $arr2 = null) {

    $args = func_get_args();

    $r = (array)current($args);

    while (($arg = next($args)) !== false) {
        foreach ((array)$arg as $key => $val)    {
            if (is_array($val) && isset($r[$key]) && is_array($r[$key])) {
                $r[$key] = merge($r[$key], $val);
            } elseif (is_int($key)) {
                $r[] = $val;
            } else {
                $r[$key] = $val;
            }
        }
    }


    return $r;
}

很遗憾,内置的 PHP 合并功能无法为我们执行此操作,但这是一个不错的选择。

【讨论】:

    【解决方案2】:

    为什么不直接使用func_get_args 函数?

    function yourFunction($keys) {
        $default_options = array('test', array('test1' => array('test2')), 'test3');
        $options = func_get_args();
        array_shift($options);
    
        $options = array_combine($keys, $options); 
        $options = array_merge($default_options, $options);
    
        print_r($options);
    }
    
    // Usage
    yourFunction(array('option1', 'option2', 'option3', 'option4'), 'optionval1', array('optionval2-1', 'optionval2-2'), 'optionval3', 4);
    

    这样你就有了一个数组开始,不需要担心其他任何事情,它可以接受任意数量的参数/参数!

    编辑:

    (第二次编辑,将 $keys 添加为第一个参数) 修改了上面的函数,这里是输出。不确定您正在寻找什么格式的输出。因此,您可能需要为给定的初始数据发布您所追求的结束数组结构。

    Array
    (
        [0] => test
        [1] => Array
            (
                [test1] => Array
                    (
                        [0] => test2
                    )
    
            )
    
        [2] => test3
        [option1] => optionval1
        [option2] => Array
            (
                [0] => optionval2-1
                [1] => optionval2-2
            )
    
        [option3] => optionval3
        [option4] => 4
    )
    

    【讨论】:

    • 这对第一步来说很好,但是然后将它与默认值合并呢?
    • 太好了,您添加了输出。但是有编号的键并没有真正的意义,因为命名参数应该有命名的键。
    • ...参数在哪里命名? “option1”等是值,不一定是名称。您可以始终将“keys”数组作为第一个参数传递,然后将其关闭并根据需要使用array_combine。使用该场景进行更新。
    【解决方案3】:

    array_merge_recursive(),但它可能无法达到您的实际预期。

    这是一个递归版本或array_merge(),它实际上的行为类似于array_merge()

    function array_merge_recursive_2($a, $b) {
            foreach($b as $key => $value) {
                    if (isset($a[$key]) && is_array($a[$key]) && is_array($value)) {
                            $a[$key] = array_merge_recursive_2($a[$key], $value);
                    } else {
                            $a[$key] = $value;
                    }
            }
            return $a;
    }
    

    【讨论】:

      【解决方案4】:

      使用array_merge_recursive()。这也会合并子数组。

      【讨论】:

      • 这个函数并没有达到人们一开始所期望的效果。当两个数组中都存在一个键时,此函数将只返回一个包含两个值的数组。 (不像array_merge。)
      • 我不知道这一点,我以前从未使用过该函数,只是猜测会有一个,因为 PHP 有数十亿个实际上并不需要的函数。无论如何,很高兴知道 xD。
      猜你喜欢
      • 2011-12-01
      • 2021-06-07
      • 1970-01-01
      • 1970-01-01
      • 2011-01-06
      • 1970-01-01
      • 2017-11-18
      • 1970-01-01
      • 2015-11-23
      相关资源
      最近更新 更多