PHP 键 => 值数组到方法参数(顺序?)
PHP key => value array to method arguments (order?)
我觉得这个挺有意思的!!! :).
我得到了什么?
在我在某些对象的某种程度上使用的应用程序中(并不重要)我得到一个数组,例如:
$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 不能很好地处理数组),这些 issets 快把我逼疯了。此外,对于将来使用此代码的人来说,这将是一场噩梦,那时我已经是一个“退休的书呆子”了。
我想要什么?
我想要这样的功能:
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']);
有什么问题?
- 这不是模板。变量个数总是不一样,名字总是不一样,有的传,有的不传。
- 它应该工作得非常快...
- 以正确的顺序调用方法参数。数组可以排序、不排序或随机排序,而方法中的参数总是以相同的顺序排列。数组应该重新排序以匹配方法参数顺序,然后调用方法。
我带来了什么?
我有一个使用 reflectionClass 的想法。我可以检查方法参数的名称,按顺序排列它们,重新排列数组并尝试调用此方法。但这是一个非常消耗资源的解决方案,因为我认为 reflectionClass 不是那么快。
解决方案使用提取?这会很棒。但是在提取之后,我需要在代码中使用确切的变量名称。而且我不了解它们,因为它们每次都不一样,我需要一种通用的方法。
NEW(感谢评论):call_user_func_array()。这很棒,但它只适用于索引数组,因此这将是可能解决方案的最后但并非最不重要的一步。由于参数的顺序仍然未知...
这个问题有很好的语义、实用的解决方案吗?
我又看了一遍我的问题,希望能看清楚。如果没有,请post发表评论,我会尽力更好地描述问题。
考虑维护者的荣誉,但我认为简单性与良好的语义和实用主义一样重要。考虑一下:如果您不得不问如何编写这样的模式,那么 reader 显而易见的可能性有多大?我宁愿遇到我只能思考 "Yep, that's clear" 而不是 "Oh cool that's a really intricate and clever way of setting array defaults".
的代码
考虑到这一点,在我看来,在更适合 class 的情况下使用数组。您有一个 ID、一个标签和一个名称,它们肯定代表一个实体——正是 classes 的用途! 类 可以轻松设置默认值并提供 PHP 每个属性的文档。您可以拥有一个构造函数,该构造函数仅采用一个现有数组并 array_merge()
使用一组默认值对其进行处理。为了方便地进行反向转换,将对象转换为 PHP 中的数组会生成其属性的关联数组。
尝试使用 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']);
我觉得这个挺有意思的!!! :).
我得到了什么?
在我在某些对象的某种程度上使用的应用程序中(并不重要)我得到一个数组,例如:
$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 不能很好地处理数组),这些 issets 快把我逼疯了。此外,对于将来使用此代码的人来说,这将是一场噩梦,那时我已经是一个“退休的书呆子”了。
我想要什么?
我想要这样的功能:
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']);
有什么问题?
- 这不是模板。变量个数总是不一样,名字总是不一样,有的传,有的不传。
- 它应该工作得非常快...
- 以正确的顺序调用方法参数。数组可以排序、不排序或随机排序,而方法中的参数总是以相同的顺序排列。数组应该重新排序以匹配方法参数顺序,然后调用方法。
我带来了什么?
我有一个使用 reflectionClass 的想法。我可以检查方法参数的名称,按顺序排列它们,重新排列数组并尝试调用此方法。但这是一个非常消耗资源的解决方案,因为我认为 reflectionClass 不是那么快。
解决方案使用提取?这会很棒。但是在提取之后,我需要在代码中使用确切的变量名称。而且我不了解它们,因为它们每次都不一样,我需要一种通用的方法。
NEW(感谢评论):call_user_func_array()。这很棒,但它只适用于索引数组,因此这将是可能解决方案的最后但并非最不重要的一步。由于参数的顺序仍然未知...
这个问题有很好的语义、实用的解决方案吗?
我又看了一遍我的问题,希望能看清楚。如果没有,请post发表评论,我会尽力更好地描述问题。
考虑维护者的荣誉,但我认为简单性与良好的语义和实用主义一样重要。考虑一下:如果您不得不问如何编写这样的模式,那么 reader 显而易见的可能性有多大?我宁愿遇到我只能思考 "Yep, that's clear" 而不是 "Oh cool that's a really intricate and clever way of setting array defaults".
的代码考虑到这一点,在我看来,在更适合 class 的情况下使用数组。您有一个 ID、一个标签和一个名称,它们肯定代表一个实体——正是 classes 的用途! 类 可以轻松设置默认值并提供 PHP 每个属性的文档。您可以拥有一个构造函数,该构造函数仅采用一个现有数组并 array_merge()
使用一组默认值对其进行处理。为了方便地进行反向转换,将对象转换为 PHP 中的数组会生成其属性的关联数组。
尝试使用 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']);