PHP密钥=> value数组到方法参数(order?)

时间:2015-08-20 17:22:13

标签: php arrays methods arguments

我觉得这很有意思! :)

我得到了什么?

在我在某些对象的某个级别上使用的应用程序(并不重要)我得到一个数组,例如:

$array = array(
    'argument_label' => 'value_label',
    'argument_name' => 'value_name',
    'argument_id' => 'value_id'
)

我对创建此数组的方式和时间没有任何影响。接下来,我有一个方法:

public function arrayArgument($array) {
    $label = isset($array['argument_label']) ? $array['argument_label'] : 'default_label';
    $name = isset($array['argument_name']) ? $array['argument_name'] : 'default_name';
    $id = isset($array['argument_id']) ? $array['argument_id'] : 'default_id';

    // Do something
    return 'something';
}

我真的很讨厌它。方法参数没有适当的文档(因为PHPDocumentator对数组的工作效果不是很好),而且这些错误让我发疯。此外,对于将来会使用此代码的人来说,这将是一个噩梦,当我已经成为“退休的书呆子”时。

我想要什么?

我希望有这样的功能:

public function notArrayArgument(
    $id='default_id', 
    $label='default_label', 
    $name='default_name'
) {
    // Do something
    return 'something';
}

我能做什么?

当我得到数组时,我可以更改一些代码,然后运行自己的方法。所以我需要某种解决方案才能从这里获得:

$array = array(
    'argument_label' => 'value_label',
    'argument_name' => 'value_name',
    'argument_id' => 'value_id'
)

到这里:

notArrayArgument('value_id', 'value_label', 'value_name');

或者在这里:

notArrayArgument($array['argument_id'], $array['argument_label'], $array['argument_name']);

有什么问题?

  1. 这不是模板。变量的数量总是不同的,名称总是不同的,有时它们中的一些被传递,有时则不传递。
  2. 它应该工作得非常快......
  3. 按正确的顺序调用方法参数。数组可以排序,不排序或随机排序,而方法内的参数总是以相同的顺序排序。应该重新排序数组以匹配方法参数顺序,然后应该调用该方法。
  4. 我带来了什么?

    1. 我有一个使用 reflectionClass 的想法。我可以检查方法参数的名称,按顺序获取它们,重新排序数组并尝试调用此方法。但这是一个非常资源化的解​​决方案,因为我认为reflectionClass不是那么快。

    2. 使用提取的解决方案?这会很棒。但是在提取之后,我需要在代码中使用确切的变量名。而且每次他们不同时我都不知道他们,我需要一种普遍的方法。

    3. 新(请注释):call_user_func_array()。它很棒,但它只适用于索引数组,所以这将是可能解决方案的最后但并非最不重要的一步。由于论证的顺序仍然未知......

    4. 这个问题是否有一个很好的语义,实用的解决方案?

      我再次阅读了我的问题,希望能够清楚地理解。如果没有,请发表评论,我会尽力更好地描述问题。

2 个答案:

答案 0 :(得分:2)

Kudos考虑维护者,但我认为简单与良好的语义和实用主义同样重要。考虑一下:如果你不得不问如何编写这样一个模式,那么它对读者来说有什么可能是显而易见的?我更愿意遇到代码,我可以认为“是的,这是明确的”而不是“哦,很酷,这是一个非常复杂和聪明的设置数组默认值的方式”

考虑到这一点,在我看来,数组正在更适合某个类的情况下使用。你有一个id,一个标签和一个名字,它肯定代表一个实体 - 确切地说是什么类!类可以很容易地设置默认值并在每个属性上提供PHPDoc。你可以有一个构造函数,它只需要一个现有的数组,array_merge()就可以得到一个默认数组。对于反向转换,方便的是,在PHP中将对象转换为数组会产生其属性的关联数组。

答案 1 :(得分:1)

尝试使用George Brighton提到的课程。

如果您不能使用遗留或库约束,则必须使用反射。不要过多担心反射类的性能,很多框架都使用它们来执行请求路由。  您可以使用以下功能:

function arrayArgument($object, $method, $array)
{
    $arguments = [];
    $reflectionMethod = new ReflectionMethod(get_class($object), $method);
    foreach ($reflectionMethod->getParameters() as $parameter)
    {
        $arguments[] = isset($array[$parameter->name]) ? $array[$parameter->name] : $parameter->getDefaultValue();
    }
    call_user_func_array(array($object, $method), $arguments);
}

所以你可以做到

$instance = new MyClass();
arrayArgument($instance, 'notArrayArgument', ['name' => 'myname']);