我在具有签名的Yii 1.8中包装模型函数:
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
具有未在$_params
中定义的密钥以及指定该密钥的消息的情况下抛出异常,并且希望这样做如果可能,array_merge
的一部分。
答案 0 :(得分:1)
使用单个参数或参数数组的决定是基于意见的。这取决于实际情况。至少我会在整个项目中保持设计的一致性。
要确定是否传递了未知参数,您可以使用array_diff()
:
$a = array(
'test' => 'foo',
'name' => 'bar'
);
$b = array(
'test' => 'foo',
'name' => 'bar',
'abcd' => '123'
);
$d = array_diff(
array_keys($b), array_keys($a)
);
echo "The following keys can't be understood: " . implode(', ', $d) . PHP_EOL;
然而,我会跳过那张支票,因为它不会伤害"如果有未知参数。
答案 1 :(得分:1)
对于1),是的,传递数组是不支持命名参数的语言中常见的蹩脚解决方法(请参阅jQuery等)。使用新的数组语法,这甚至几乎可读:
$some->save([
$runValidation => true,
$attributes => ['foo', 'bar']
]);
在函数内部,您可以使用extract
来避免丑陋的$params[foobar]
引用。
为了获得更好的品味,请说服@NikiC让this patch做好准备))
至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....