PHP良好实践 - 参数过多的方法

tho*_*hom 6 php parameters methods search arguments

我已经为我网站上的搜索内容制作了一个类和方法.它有太多参数,搜索参数.我的控制器从表单中获取数据,然后传递给模型.

public function search($name, $age, $foo, ... $bar, $lorem) {
Run Code Online (Sandbox Code Playgroud)

这种方法有什么提示吗?也许是一个关于参数太多的方法的好习惯.谢谢.

编辑:

参数用于搜索... $ name应该搜索值为$ name $ age的人应该搜索值为$ age的人等等...类似于SQL Where子句.

再次感谢.

OZ_*_*OZ_ 12

DarhazerZanathel已经给出了很好的答案,我只想向您展示一件事:具有流畅界面的制定者.仅当所有参数都是可选的时.

$finder->
 setName($name)->
 setAge($age)->
 setFoo($foo)->
 setBar($bar)->
 setLorem($lorem)->
 search();
Run Code Online (Sandbox Code Playgroud)

要么

$query = new SearchQuery($required_argument);
$query->setAge($optional)->setLorem($optional);

$finder->search($query);
Run Code Online (Sandbox Code Playgroud)

创建流畅的界面,只需写入setter的正文return $this;


web*_*com 6

我喜欢将数组用于可能/有许多参数的函数.这种方法允许接近无限扩展参数,并且比使用类似的东西更直接和更好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;
}
Run Code Online (Sandbox Code Playgroud)

...或者您可以使用面向对象的方法:

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
    }
}
Run Code Online (Sandbox Code Playgroud)