传递一个数组来设置变量

发布于 2024-09-04 18:43:38 字数 543 浏览 15 评论 0原文

我在阅读php代码时经常看到这样的习惯用法:

public function __construct($config)
{
    if (array_key_exists('options', $config)) {
       ...
    }
    if (array_key_exists('driver_options', $config)) {
        ...
    }
}

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

(defun ct (&key options driver_options) 
       (do-something-with-option-and-driver_option))

但由于我在 PHP 中,我宁愿有一个构造函数,它接受参数列表,并在不需要时让它们为空。

那么,你们对于将数组作为 other 中的参数来进行一些初始化或其他操作有何看法?

在回答其他问题时,您必须考虑函数用户和 API 设计者的观点。

I often see this idiom when reading php code:

public function __construct($config)
{
    if (array_key_exists('options', $config)) {
       ...
    }
    if (array_key_exists('driver_options', $config)) {
        ...
    }
}

Here I am concern with the way the parameter is used.
If I were in lisp I would do:

(defun ct (&key options driver_options) 
       (do-something-with-option-and-driver_option))

But since I am in PHP I would rather have a constructor that take a list of parameter and let them be null if there a not require.

So what do you guys think about having an array as parameter in other to do some initialization-or-whatever?

In other to answer you have to take in account the point of view of the user of the function and the designer of the API.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

高跟鞋的旋律 2024-09-11 18:43:38

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

问题是我无法通过查看函数签名来知道数组不能采用的元素。最重要的是,这些实现几乎从不检查是否有任何无法识别的键,因此如果我拼错了数组键,我不会收到警告。

更好的选择是传递配置对象。至少,IDE 可以为我提供有关可用配置对象的提示,并且可以将计算出的缺失选项的默认值从您向配置对象中的 getter 显示的构造函数中移走。明显的替代方案是为多个配置选项提供设置器;尽管这对每个所需的没有帮助,但无法提供默认值。

Personally, I dislike that idiom. I prefer to have a long parameter list instead, if necessary.

The problem is that I can't know the elements the array can't take by looking at the function signature. On top of that, the implementations almost never check if there's any key that's not recognized, so if I mispell an array key, I get no warning.

A better alternative would be passing a configuration object. At least, there the IDE can provide me hints on the available configuration objects and the calculated default values for missing options can be moved away from the constructor you show to the getters in the configuration object. The obvious alternative is to provide setters for the several configuration options; though this doesn't help for the required ones for each no default can be provided.

玩套路吗 2024-09-11 18:43:38

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

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

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 [

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

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

一件事。 如果您这样做,请记录所需的选项。这将使那些关注您的人的生活变得更加轻松。

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

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

一件事。 如果您这样做,请记录所需的选项。这将使那些关注您的人的生活变得更加轻松。

I very much like the design pattern of "options arrays". If PHP supported Python's argument expansion, then I would agree to go with a long parameter list. But I just find foo(1, 2, 'something', true, 23, array(4), $bar); to be REALLY un-readable. I typically will use arrays when there are more than about 3 or 4 parameters that need to be set...

What I would suggest to "clean up" the constructor, is create a protected method for accessing config vars (preferably in a base class):

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 [

Then, in your class, you can overload the requireOptions array to define things that need to be set

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

One thing. If you do this, PLEASE document the options required. It will make life a lot easier for those that follow you.

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

Then, in your class, you can overload the requireOptions array to define things that need to be set

One thing. If you do this, PLEASE document the options required. It will make life a lot easier for those that follow you.

×纯※雪 2024-09-11 18:43:38

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

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

I find using arrays as parameters to be helpful when there are a lot of optional parameters. Usually I'll use an array_merge to merge the passed array with the "defaults" array. No checking required. If you have required parameters, you can use array_diff_key to determine if any required parameters are missing.

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文