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

时间:2011-07-04 19:02:21

标签: php search methods parameters arguments

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

public function search($name, $age, $foo, ... $bar, $lorem) {

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

编辑:

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

再次感谢。

6 个答案:

答案 0 :(得分:12)

Darhazer Zanathel 已经给出了很好的答案,我只想告诉你一件事:具有流畅界面的setter。仅当所有参数都是可选的时。

$finder->
 setName($name)->
 setAge($age)->
 setFoo($foo)->
 setBar($bar)->
 setLorem($lorem)->
 search();

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

$finder->search($query);

创建fluent interface,只需写入setter的正文return $this;

答案 1 :(得分:4)

我喜欢将数组用于可能/有许多参数的函数。这种方法允许接近无限扩展参数,并且比使用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;
}

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

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

答案 2 :(得分:2)

您可以将内容打包到基于键=&gt;值的数组

示例:

$params = array("Name"=>"Bob", "Age"=32.....);
Class->search($params);
public function search($params) {
    // access keys
}

这有点疲惫,因为该方法可能非常容易使用,因为任何数组都可以传入。在某些其他方法调用中可能需要进行一些验证以验证数组内容。

编辑:由于评论中有一些争论......这是另一种方法来做到这一点

创建一个新类!包含名称年龄等的用户类以及其他任何人口统计信息。无论如何,你可能会在其他地方使用它们。

将一个或多个对象作为参数传递

$object = new Object();
SearchClass->search($object)

public function search(Object $object){
     // Do junk here
}

答案 3 :(得分:2)

我使用最接近的value objects比喻,在那里传递一个对象,其中包含所有必要参数作为函数的属性。

<?php
class FilterVO {
    public $id;
    public $name;
    // etc ...
}

class SomeCollection {
    public function FilterResults(FilterVO $prefs) {
        // got all the goodies in here
    }
}
?>

答案 4 :(得分:1)

答案 5 :(得分:0)

使它接受一个数组作为参数,具有许多名称 - 值对。然后,您可以使用extract($paramsArray)将数组中的所有名称设为$ variables。