首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在PHP中测试可选参数

在PHP中测试可选参数
EN

Stack Overflow用户
提问于 2011-12-19 21:55:53
回答 2查看 2.2K关注 0票数 17

我有一些跨类的"setter“方法,为了方便起见,我添加了一个可选的参数$previous,该参数通过引用接受一个参数,并用现有的值填充它,然后用新的值替换它。例如:

代码语言:javascript
复制
public function set_value($key, $value, &$previous = null)
{
    $previous = $this->get_value($key);
    $this->_values[$key] = $value;
    return $this;
}

这可以很好地工作;但是在某些情况下,相应的"getter“方法是有点进程密集型的,并且无条件地运行它是一种浪费。我想我可以测试一下:

代码语言:javascript
复制
if(null !== $previous)
{
    $previous = $this->get_value($key);
}

但是这并不起作用,因为作为$previous的参数传递的变量之前并没有在它的作用域中定义,而且它的缺省值无论如何都是null。我想出来的唯一解决方案是:

代码语言:javascript
复制
public function set_value($key, $value, &$previous = null)
{
    $args = func_get_args();
    if(isset($args[2])
    {
        $previous = $this->get_value($key);
    }
    $this->_values[$key] = $value;
    return $this;
}

或者,用一行来表示:

代码语言:javascript
复制
if(array_key_exists(2, func_get_args()))
{
    // ...
}

我不喜欢方法体依赖于参数索引(当它看起来不必要的时候),有没有更干净的方法来实现我想要的东西?

我试过了:

代码语言:javascript
复制
if(isset($previous)){}

if(!empty($previous)){}

if(null !== $previous){}

两者都不起作用。

到目前为止可能的解决方案:

代码语言:javascript
复制
if(func_num_args() == $num_params){}

if(array_key_exists($param_index, func_get_args())){}

// 5.4
if(isset(func_get_args()[$param_index])){}

// 5.4
if(func_num_args() == (new \ReflectionMethod(__CLASS__, __FUNCTION__))
    ->getNumberOfParameters()){}

@DaveRandom --所以,在以下方面:

代码语言:javascript
复制
define('_NOPARAM', '_NOPARAM' . hash('sha4096', microtime()));

function foo($bar = _NOPARAM)
{
    // ...
}

@hoppa --使用案例:

代码语言:javascript
复制
$obj->set_something('some_key', $some_value, $previous) // set
    ->do_something_that_uses_some_key()
    ->set_something('some_key', $previous) // and reset
    ->do_something_that_uses_some_key()
    -> ...

而不是:

代码语言:javascript
复制
$previous = $obj->get_something('some_key'); // get
$obj->set_something('some_key', $some_value) // set
    ->do_something_that_uses_some_key();
    ->set_something($previous) // and reset
    ->do_something_that_uses_some_key();
    -> ...
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-12-20 01:38:37

可能不是您想要解决问题的方式(测试可选参数),但我会这样实现它:

代码语言:javascript
复制
public function set_value($key, $value)
{
    $this->_values[$key] = $value;
    return $this;
}
public function set_get_value($key, $value, &$previous)
{
    $previous = $this->get_value($key);
    $this->_values[$key] = $value;
    return $this;
}

使用案例示例:

代码语言:javascript
复制
$obj->set_get_something('some_key', $some_value, $previous) // set AND get
    ->do_something_that_uses_some_key()
    ->set_something('some_key', $previous) // and reset
    ->do_something_that_uses_some_key()
    -> ...

为什么要使用另一个函数?

此解决方案有以下几个优点:

  1. 名称更明确,其他代码更少混淆
  2. 没有隐藏的副作用
  3. 解决了(未定义的)变量已经具有值
  4. 没有调用func_num_args的开销的问题,或者其他一些“元”函数<代码>H213<代码>G214

编辑:代码中的拼写错误。

编辑2:删除了&$previous set_get_value()函数的默认值(感谢draevor)

票数 3
EN

Stack Overflow用户

发布于 2011-12-20 01:16:02

摘自上面的评论/讨论:

为了检查参数是否被传递,你有两个选择--检查参数的值和一个值(就像你对null所做的那样)或者检查参数的数量。

如果使用第一个选项,则没有不能从函数外部传递的值,因此总是有可能出现误报(现在发生的情况与null相同)。DaveRandom使用随机字符串的例子在大多数情况下应该足够了,但我认为这有点过头了。

我认为第二个选项是最干净的(快速,可读等)。作为对func_get_args的一个小改进,我将使用func_num_args -这样您将检查传递的参数的数量,而不是参数索引。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8562359

复制
相关文章

相似问题

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