传递数组以设置变量

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了传递数组以设置变量相关的知识,希望对你有一定的参考价值。

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

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

这里我关心参数的使用方式。如果我在口齿不清,我会这样做:

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

但是因为我在PHP中,我宁愿有一个构造函数来获取参数列表,如果没有需要,让它们为null。

那么你们怎么看待将数组作为参数在其他方面做一些初始化或者什么呢?

在其他答案中,您必须考虑该功能的用户和API的设计者的观点。

答案

就个人而言,我不喜欢这个成语。如果需要,我更喜欢使用长参数列表。

问题是我无法通过查看函数签名来了解数组无法获取的元素。最重要的是,实现几乎从不检查是否有任何密钥无法识别,所以如果我拼错了数组密钥,我就不会收到警告。

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

另一答案

我非常喜欢“选项数组”的设计模式。如果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 [$'.$option.'] was not set');
            }
        }
    }

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

然后,在您的类中,您可以重载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
        }
    }
}

一件事。如果您这样做,请记录所需的选项。对于那些关注你的人来说,它会让生活变得更轻松。

另一答案

当有很多可选参数时,我发现使用数组作为参数是有用的。通常我会使用array_merge将传递的数组与“defaults”数组合并。无需检查。如果您有必需的参数,则可以使用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);
}

以上是关于传递数组以设置变量的主要内容,如果未能解决你的问题,请参考以下文章

如何创建片段以重复变量编号中的代码行

如何使用Android片段管理器传递变量[重复]

Alamofire 文件上传出现错误“JSON 文本未以数组或对象开头,并且允许未设置片段的选项”

如何在导航抽屉活动模板中的片段之间传递字符串变量

解析:JSON 文本没有以数组或对象开头,并且允许未设置片段的选项

Android:将片段和弹出窗口的点击事件中生成的变量传递给活动的方法