PHP Good practices - Methods with too many parameters PHP Good practices - Methods with too many parameters php php

PHP Good practices - Methods with too many parameters


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 classclass 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}