我有一个模型,它在SQL中使用一堆条件运行查询。因此,模型需要接受很多参数,例如:
this->model_name->method($param1, $param2, ... )在模型方面,我通常将其设置为
function method($param1 = NULL, $param2 = NULL, ... )这些参数中的每一个都是可选的,应用程序的用例也会有所不同。所以我的问题是:在什么时候(如果有的话)开始通过数组将这些参数传递给方法是有意义的,比如:
$params = [
'param1' => 'whatever',
'param2' => 'whatever',
...
]
this->model_name->method($params)我想最终的目标是,代码更整洁,method(null, null, null, null, $param)的实例更少,除非这是可以做的事情。
发布于 2013-03-12 03:33:00
大多数答案都支持数组方法(一般来说,我也会同意),但我将扮演魔鬼的倡导者,并列出一些负面影响:
中的文档不太清晰
记录函数/方法的大多数方法都会单独列出该函数的参数。例如,具有基本DocBlock的函数将如下所示:
/**
* A function that accepts an array of params
* @param array $param_array An array of key=>value arguments
*/
function accept_array($param_array = array('key1' => 'first_val', 'key2' => 'second_val')) {
var_dump($param_array);
}请注意,DocBlock并不直接支持$param_array的各个部分,而只是将数组作为一个整体。相比之下,单独列出所有参数如下所示:
/**
* A function that 'normal' params
* @param string $key1 First argument
* @param string $key2 Second argument
*/
function accept_normal($key1 = 'first_val', $key2 = 'second_val') {
echo $key1;
echo $key2;
}如果你希望你的函数是完全自文档化的,这也是一个问题,因为在第一个例子中,你不需要在函数本身中实际列出你期望的参数。
默认值可能不会像预期的那样工作
“正如预期的那样”可能有点过头了(这可能是最明显的问题之一),但请看下面的例子:
function accept_array($param_array = array('key1' => 'first_val', 'key2' => 'second_val')) {
var_dump($param_array);
}
accept_array(array('key2' => 'a_different_val'));有些人可能希望var_dump包含默认值key1和新值key2,但整个数组都被替换了,这意味着您需要记住在每个函数中手动设置每个键的默认值,如下所示:
function accept_array($param_array = array()) {
if (!isset($param_array['key1'])) { $param_array['key1'] = 'first_val'; }
if (!isset($param_array['key2'])) { $param_array['key2'] = 'second_val'; }
var_dump($param_array);
}
accept_array(array('key2' => 'a_different_val'));否自动过滤
以“正常”的方式列出参数还会给你一组内置的过滤器。举个例子,快速而肮脏的用户搜索:
/**
* We want to allow searching for users by user_id or email only!
* @param array $param_array
*/
function find_user($param_array = array('user_id' => 0, 'email' => '')) {
foreach ($param_array as $field => $value) {
$this->db->or_where($field, $value);
}
$this->db->get('users');
}
find_user(array('first_name' => 'Joe', 'last_name' => 'Bloggs'));无需在$param_array上手动添加一些“接受的键”类型验证,对find_user()函数的调用基本上可以使用它喜欢的任何字段。更简单的版本显然看起来像这样:
/**
* We want to allow searching for users by user_id or email only!
* @param int $user_id
* @param string $email
*/
function find_user($user_id = 0, $email = '') {
$this->db->or_where('user_id', $user_id);
$this->db->or_where('email', $email);
$this->db->get('users');
}
// No way for me to submit any other fields, they'll just fail when they get to the query
find_user('Joe', 'Bloggs')); 我承认其中一些是入门级的,可能还有更多我遗漏的(请随意评论更多,我会将它们复制到回复中),但希望有足够的内容让人们在自动使用“数组方法”时三思而后行,而不用考虑手动验证和文档编制等问题。
发布于 2013-03-12 00:32:07
传递参数数组为自文档化代码提供了更好的选择。
当我使用许多参数时,我经常发现自己使用的样式如下:
// do_something_model($enable_option1,$enable_option2,$enable_option3)
do_something_model(FALSE, TRUE, FALSE)其中我带了一个带有参数名称的注释行,以提醒自己如何使用模型。
在这种情况下,使用具有有意义命名的键的数组可以提供有用的助记符。
最近,我还使用了更多的包装器函数。例如,我可能让我的基本模型方法从一个表中获取所有数据,该方法将有几个选项。
然后,我定义了一个执行特定任务的新方法,然后使用正确的选项调用其中的基本方法。
脚注
我发现,如果我的方法有“太多的选择”,最好重新考虑方法的目的,并将其分解为两个或更多更容易使用的专门方法。
发布于 2013-03-12 00:28:15
我也推荐数组版本。Symfony2也经常使用这种模式,例如在渲染模板、创建表单类和创建http响应等方面。您只需确保清楚地记录了所有可能的参数。
https://stackoverflow.com/questions/15343404
复制相似问题