Php 检查数组传递到函数中的参数
我在Yii 1.8中包装了一个模型函数,其签名如下:Php 检查数组传递到函数中的参数,php,Php,我在Yii 1.8中包装了一个模型函数,其签名如下: public save($runValidation=true, array $attributes=NULL) 具有以下功能: public xSave(array $params) 这允许添加标志和可选消息,在委托的save()函数返回false的情况下,该标志和消息会导致包装函数引发异常 我曾想过用以下内容覆盖save(): public save( $runValidation=true, array $attribute
public save($runValidation=true, array $attributes=NULL)
具有以下功能:
public xSave(array $params)
这允许添加标志和可选消息,在委托的save()
函数返回false
的情况下,该标志和消息会导致包装函数引发异常
我曾想过用以下内容覆盖save()
:
public save(
$runValidation=true,
array $attributes=NULL,
$exception_on_error=false,
$exception_message=false
)
但是我想允许后两个参数的规范独立于第一个参数,并且允许使用字符串键传入数组的额外可读性
到目前为止,我已经:
/**
* Enhanced save function.
* Delegates to standard model save to allow exceptions to be thrown
* in the case where the model was not saved.
**/
public function xSave(array $params=array()){
$_params=array(
'run_validation'=>true,
'attributes'=> null,
'exception_on_failure'=>false,
'exception_message'=>false,
);
array_merge($_params, $params);
// Call the save method.
$is_saved=$this->save($_params['run_validation'],$_params['attributes']);
// Throw exception to if flag set and model not saved.
if($_params['exception_on_failure'] && !$is_saved){
// If no exception message was passed in, use the default.
if($_params['exception_message'] === false){
throw new CException('
Could not '.($this->isNewRecord()?'create':'update').' '.get_class($this).';
Errors: '.CJSON::encode($this->errors)
);
}
// Else throw using the one provided.
throw new CException($exception_message);
}
// Return result of standard save method.
return $is_saved;
}
首先,我想知道这是否是一个明智的选择,因为我可能会在系统的其他部分使用它。我目前不太担心参数的类型,尽管我同意这可能是未来的一个问题
其次,我还希望能够在
$params
有一个未在$\u params
中定义的键的情况下抛出异常,并显示一条指定该键的消息,如果可能的话,希望将此作为数组合并的一部分。使用单个参数或参数数组的决定是基于意见的。这要视情况而定。至少我会在整个项目中保持设计的一致性
要确定是否传递了未知参数,可以使用
array\u diff()
:
但是,我会跳过该检查,因为如果存在未知参数,它不会“有害”。到1),是的,在不支持命名参数的语言中,传递数组是常见的蹩脚解决方法(请参见jQuery等)。使用新的数组语法,这甚至几乎是可读的:
$some->save([
$runValidation => true,
$attributes => ['foo', 'bar']
]);
在函数内部,可以使用来避免丑陋的$params[foobar]
引用
不过,为了更好的品味,请说服他们做好准备。)
到2)如果你系统地使用参数数组,考虑这样的帮助函数:
function parseArgs($args, $defaults) {
foreach($args as $k => $v) {
if(!array_key_exists($k, $defaults))
throw new Exception("invalid argument: $k");
// might want to add some type checking, like
// if(gettype($v) != gettype($defaults[$k])) bang!
}
return $args + $defaults;
}
用法:
public function xSave(array $params=array()){
extract(parseArgs($params, [
'run_validation'=>true,
'attributes'=> null,
'exception_on_failure'=>false,
'exception_message'=>false,
]));
if ($run_validation)
etc....
你有没有考虑过
func\u get\u args
?谢谢,我正在考虑这样做,以便第一个无法识别的密钥将被排除在外,而不是整个参数数组。如果有人用错误的键调用函数,未知参数可能有害。。在我的例子中,他们认为“失败时的异常”是“失败时的异常”,这个参数在没有检查的情况下会被忽略,没有错误,函数也不会按预期执行。我希望array\u diff()
在大多数使用情况下比自定义foreach更快。当然,需要一个基准来证明这一点抱歉,我误解了你的解决方案。。现在我看到只有无法识别的键被打印出来了。Yum,就像命名参数一样!不知道extract,但将研究它和helper函数。谢谢您的时间。如果没有看到基准测试,我会说这比只使用array\u diff()
要慢。当然,“坏”的数组大小和/或位置中存在阈值element@hek2mgl:鉴于参数列表通常很小(@georg Yes参数列表很小,但在web应用程序中有许多函数/方法调用。因此,我认为分析差异会很有趣。但是,我不想太挑剔,我仍然不确定我是否正确。(需要调查)
public function xSave(array $params=array()){
extract(parseArgs($params, [
'run_validation'=>true,
'attributes'=> null,
'exception_on_failure'=>false,
'exception_message'=>false,
]));
if ($run_validation)
etc....