4

我有一个模型在 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)除非这是一件可以做的事情。

4

4 回答 4

2

大多数答案都支持数组方法(一般来说,我也会同意),但我会扮演魔鬼的拥护者并列出一些负面因素:

文档不太清楚

大多数记录函数/方法的方法将单独列出该函数的参数。例如,具有基本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-11T19:32:59.583 回答
1

传递参数数组为自记录代码提供了更好的选择。

当我使用许多参数时,我经常发现自己使用的样式如下:

// do_something_model($enable_option1,$enable_option2,$enable_option3) 
   do_something_model(FALSE,          TRUE,           FALSE)

我在其中带有参数名称的注释行,以提醒自己我是如何使用模型的。

在这种情况下,使用具有有意义命名键的数组提供了有用的助记符。

最近,我也在使用更多的包装函数。例如,我可能有我的基本模型方法确实从表中获取我的所有数据,并且此方法将有几个选项。

然后,我定义了一个新方法来执行特定任务,然后使用正确的选项调用其中的基本方法。

脚注
我发现,如果我的方法有“太多选择”,最好重新考虑方法的目的,并将其分解为两个或多个更易于使用的专门方法。

于 2013-03-11T16:32:06.570 回答
0

我也会推荐阵列版本。Symfony2 也大量使用这种模式,例如在渲染模板、创建表单类和创建一般的 http 响应中。您只需确保清楚地记录所有可能的参数。

于 2013-03-11T16:28:15.027 回答
0

你可以走任何一条路,但数组肯定会让你的方法更干净。将参数作为数组传递是非常有意义的。

于 2013-03-11T16:28:45.700 回答