Optimal adjustment of model parameter parameters?

I have a model that runs a query with a bunch of conditions in SQL. As a result, the model should take many parameters, i.e.

this->model_name->method($param1, $param2, ... ) 

On the model side, I usually set this as

 function method($param1 = NULL, $param2 = NULL, ... ) 

Each of these options is optional, and use cases will vary by application. So my question is: at what point (if ever) does it make sense to start passing these parameters to the method through the array, a la:

 $params = [ 'param1' => 'whatever', 'param2' => 'whatever', ... ] this->model_name->method($params) 

For the ultimate purpose, I suppose cleaner code and fewer instances of method(null, null, null, null, $param) if that doesn't work well.

+4
source share
4 answers

Most of the answers supported the array method (which, generally speaking, I also agree), but I will play the devil's advocate and list some negatives:

The documentation is less clear.

Most methods for documenting functions / methods will list the parameters for this function individually. For example, a function with a basic DocBlock would look like this:

 /** * 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); } 

Note that DocBlock does not support direct support for individual parts of $param_array , but the entire array as a whole. On the contrary, listing all arguments individually is as follows:

 /** * 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; } 

This is also a problem if you expect your functions to be self-documenting enough, since in the first example you do not need to actually list the expected arguments in the function itself.


The default values ​​may not work as expected.

“As expected” is probably a slightly loaded phrase (and this is probably one of the most obvious problems), but take the following:

 function accept_array($param_array = array('key1' => 'first_val', 'key2' => 'second_val')) { var_dump($param_array); } accept_array(array('key2' => 'a_different_val')); 

Some might expect var_dump to include the default value of key1 and the new value of key2 , but the whole array will be replaced, which means you will need to remember to set the default values ​​for each key manually in each function, like this:

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

No auto filtering

Enumeration of arguments the "normal" way also gives you a built-in set of filters. Take, for example, this quick and dirty user search:

 /** * 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')); 

Without adding a few "accepted key" type confirmations to $param_array calling the find_user() function can essentially use any fields that it likes. The simplest version will obviously look like this:

 /** * 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')); 

I agree that some of them are a bit of an entry level, and maybe I missed a lot more (feel free to comment more, and I will copy them in return with a loan), but I hope there is enough for people to think about automatic use twice "array method" without thinking about manual validation and documentation, etc.

+2
source

Passing an array of parameters provides the best option for self-documenting your code.

When I use many parameters, I often find myself in a style similar to:

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

where I wrap a comment line with parameter names to remind myself how I am using the model.

In this case, using an array with significantly named keys gives useful mnemonics.

Recently, I have also been using more shell functions. For example, I may have my base model method really get all my data from the table, and this method will have several options.

Then I define a new method that performs a specific task, and then calls the main method inside it using the correct parameters.

Footnote
I believe that if my methods have “too many options”, it’s better to rethink the purpose of the method and break it down into two or more specialized methods that are easier to use.

+1
source

I would recommend the version of the array. Symfony2 also often uses this pattern, for example, in redistribution patterns, creating form classes, and creating HTTP responses in general. You just need to make sure that you fully document all the possible parameters.

0
source

You can go on any route, but the array will definitely keep your methods cleaner. It makes sense to pass parameters as an array.

0
source

All Articles