2013-03-11 127 views
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)的實例就會減少。

+0

看起來你似乎已經回答了你自己的問題。如果數組導致更清晰易懂的代碼,那就做吧! – mkaatman 2013-03-11 16:19:01

+0

Just Do It✔.. – tomexsans 2013-03-11 16:23:06

+0

[SOLID](http://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29)的原理之一是「許多客戶端特定的接口比一般的 - 用途接口「_ – 2013-03-11 20:56:19

回答

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); 

} 

注意如何在文檔塊不直接支持$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')); 

我接受一些是有點入門級的,有可能是更多的,我錯過了(隨時與更多的評論,我會複製他們到信用答覆),但希望有足夠的地方,讓人們考慮自動使用'陣列方法',而不考慮手動驗證和文件等。

+0

我喜歡你對文檔和默認值的評論,這兩者在決定採用哪種方法時非常重要。 – 2013-03-11 20:05:42

0

我會推薦陣列版本。 Symfony2也很多地使用這種模式,例如在模板的渲染,創建表單類和創建http響應中。你只需要確保你清楚地記錄所有可能的參數。

0

你可以去任何一條路線,但一個數組肯定會讓你的方法更清潔。將參數作爲數組傳遞是非常合理的。

1

傳遞參數數組爲您自行編寫代碼提供了更好的選擇。

當我使用許多參數,我經常發現自己使用的樣式,如:

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

,我隨身攜帶的參數名稱註釋行提醒我使用的模型怎麼了 自己。

在這種情況下,使用具有有意義的命名鍵的數組提供了有用的助記符。

最近,我也在使用更多的包裝函數。例如,我可能會使用我的 基本模型方法從表中獲取所有數據,並且此方法將有幾個 選項。

然後我定義一個新的方法來完成特定的任務,然後使用正確的選項調用其中的基本方法。

腳註
我發現,如果我的方法有「太多的選擇」,這是更好地重新思考方法的目的,並把它分解成兩個或多個特定的方法是使用更方便。

+0

你不能做'do_something_model($ enable_option1 = false,$ enable_option2 = true,$ enable_option3 = false)'?你顯然仍然需要讓它們按正確的順序排列,但是如果沒有額外的註釋行,它就會更具可讀性。 – 2013-03-11 19:34:53

+0

你寫的實際上是我如何定義我的模型。當我在我的控制器中使用我的模型方法時,這就是我使用comment-as-doc行的地方。 – 2013-03-11 20:08:28