I've made a class and method just for search things on my website. It has too many parameters, the search parameters. My controller grabs data from forms and then pass to the model.
public function search($name, $age, $foo, ... $bar, $lorem) {
Are there any tips of this kind of method? Maybe a good practice about method with too much parameters. Thanks.
EDIT:
parameters are for the search... $name should search people with value of $name $age should search people with value of $age and so on... something like the SQL Where clause.
Thanks again.
Darhazer and Zanathel already gave good answers, and I just want to show you one thing: setters with fluent interface. Only when all parameters are optional.
$finder->
setName($name)->
setAge($age)->
setFoo($foo)->
setBar($bar)->
setLorem($lorem)->
search();
or
$query = new SearchQuery($required_argument);
$query->setAge($optional)->setLorem($optional);
$finder->search($query);
to create fluent interface, just write in setter's body return $this;
I like using arrays for functions that might/have many parameters. This sort of approach allows for near infinite expansion of parameters, and is more straightforward and better than using something like func_get_args()
.
public function search(array $options = array())
{
$defaults = array(
'name' => null,
'age' => null,
'order' => null,
'limit' => null,
'offset' => null,
);
$options = array_merge($defaults, $options);
extract($options);
$select = $this->select();
if (!is_null($name)) {
$select->where('name = ?', $name);
}
if (!is_null($age)) {
$select->where('age = ?', $age, Zend_Db::INT_TYPE);
}
if (!is_null($order)) {
$select->order($order);
}
if (!is_null($limit) || !is_null($offset)) {
$select->limit($limit, $offset);
}
$results = $this->fetchAll($select);
return $results;
}
...or you can use an object oriented approach:
class SearchQuery
{
public function __construct(array $options = null)
{
if (!is_array($options)) {
return;
}
if (array_key_exists('name', $options)) {
$this->setName($options['name']);
}
if (array_key_exists('age', $options)) {
$this->setAge($options['age']);
}
}
public function setName($name)
{
if (!is_string($name)) {
throw InvalidArgumentException('$name must be a string');
}
$this->_name = $name;
return $this;
}
public function setAge($age)
{
if (!is_numeric($age) || $age <= 0) {
throw new InvalidArgumentException('$age must be a positive integer');
}
$this->_age = $age;
return $this;
}
}
// then you can use dependency injection in your main search class
class SearchService
{
public function search(SearchQuery $query)
{
// search
}
}
You could pack things into a key=>value based array
Example:
$params = array("Name"=>"Bob", "Age"=32.....);
Class->search($params);
public function search($params) {
// access keys
}
This is a little bit weary because the method could be used incorrectly very easily since any array could be passed in. Some validation may be required in some other method call to verify the arrays contents.
Edit: Since there has been some debate in the comments.... here is another way to do this
Create a new class! A user class that contains name age and such and whatever other demographics. You'll probably use those in other places anyway.
Pass the object or objects in as arguments
$object = new Object();
SearchClass->search($object)
public function search(Object $object){
// Do junk here
}
Introduce Parameter Object
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With