首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >传递用于设置变量的数组

传递用于设置变量的数组
EN

Stack Overflow用户
提问于 2010-06-07 23:13:07
回答 3查看 268关注 0票数 1

在阅读php代码时,我经常看到这个成语:

代码语言:javascript
运行
复制
public function __construct($config)
{
    if (array_key_exists('options', $config)) {
       ...
    }
    if (array_key_exists('driver_options', $config)) {
        ...
    }
}

这里我关注的是参数的使用方式。如果我在lisp中,我会这样做:

代码语言:javascript
运行
复制
(defun ct (&key options driver_options) 
       (do-something-with-option-and-driver_option))

但是因为我是在PHP中,所以我宁愿有一个构造函数,它接受一个参数列表,如果不需要,就让它们为null。

那么你们觉得在other中使用一个数组作为参数来做一些初始化之类的事情怎么样?

在其他回答中,你必须考虑到函数用户和API设计者的观点。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-06-07 23:21:48

就我个人而言,我不喜欢这个成语。如果需要的话,我更喜欢有一个很长的参数列表。

问题是,我不能通过查看函数签名来知道数组不能接受的元素。最重要的是,实现几乎不会检查是否有任何键无法识别,所以如果我错误地拼写了数组键,我就不会收到任何警告。

更好的替代方法是传递一个配置对象。至少,IDE可以提供有关可用配置对象的提示,并且可以将计算出的缺少选项的默认值从您向配置对象中的getter显示的构造函数中移出。一种显而易见的替代方法是为几个配置选项提供setter;尽管这对每个选项所需的setter没有帮助,但不能提供默认值。

票数 1
EN

Stack Overflow用户

发布于 2010-06-07 23:37:09

我非常喜欢“选项数组”的设计模式。如果PHP支持Python的参数扩展,那么我会同意使用长参数列表。但是我发现foo(1, 2, 'something', true, 23, array(4), $bar);真的很难读。当需要设置的参数超过3到4个时,我通常会使用数组……

为了“清理”构造函数,我建议创建一个受保护的方法来访问配置变量(最好是在基类中):

代码语言:javascript
运行
复制
abstract class Configurable {
    protected $options = array();
    protected $requiredOptions = array();

    public function __construct(array $options = array()) {
        $this->options = $options;
        foreach ($this->requiredOptions as $option) {
            if (!isset($this->options[$option])) {
                throw new InvalidArgumentException('Required argument [$'.$option.'] was not set');
            }
        }
    }

    protected function _getOption($key, $default = null) {
        return isset($this->options[$key]) ? $this->options[$key] : $default;
    }
}

然后,在您的类中,可以重载requireOptions数组来定义需要设置的内容

代码语言:javascript
运行
复制
class Foo extends Configurable {
    protected $requiredOptions = array(
        'db',
        'foo',
    );

    public function __construct(array $options = array()) {
        parent::__construct($options);
        if ($this->_getOption('bar', false)) {
            //Do Something
        }
    }
}

有一件事。如果执行此操作,请记录所需的选项。这将使那些关注你的人的生活变得容易得多。

票数 1
EN

Stack Overflow用户

发布于 2010-06-07 23:58:40

我发现当有很多可选参数时,使用数组作为参数会很有帮助。通常我会使用array_merge将传递的数组与"defaults“数组合并。不需要检查。如果您有必需的参数,可以使用array_diff_key来确定是否缺少任何必需的参数。

代码语言:javascript
运行
复制
function params($p_array) {
    static $default_vals = array('p1'=>1, 'p2'=>null, 'p3'=>'xyz');
    static $rqd_params = array('p1'=>null, 'p3'=>null);
    // check for missing required params
    $missing_params = array_diff_key($rqd_params, $p_array);
    if ( count($missing_params)>0 ) {
       //return an error (i.e. missing fields)
       return array_keys($missing_params);
    }
    // Merge passed params and override defaults
    $p_array = array_merge($default_vals, $p_array);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2990674

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档