常见误区 - load数据失败 ¶
作者:KK
发表日期:2017.4.12
复述一下load ¶
如果根据官方教程用ActiveForm构造前端表单,再提交数据到后端,基于这种场合我先示例一下平时load的过程:
$post = Yii::$app->request->post();
/*
实际上此时的结构如下:
$post = [
'UserForm' => [
'name' => 'aaa',
'age' => 11,
]
]
*/
$model = new UserForm();
$model->load($post);
echo $model->name; //aaa
echo $model->age; //11
其中要注意$post数据的结构,name和age外面还有一层叫UserForm
的key,这个key和模型的名称是一模一样的,这个key也是ActiveForm根据模型名称生成出来的
load方法的简化版 ¶
接下来我来写一个load方法的简单版,你看看代码估计就很快明白load干哪些事了
namespace yii\base;
class Model{
public function load($data, $modelName = null){
if($modelName === null){
//如果没有指定模型名字
$reflector = new ReflectionClass($this);
//得到短类名,比如类名是 app\models\UserForm 那就是得到 UserForm 这一部分
$modelName = $reflector->getShortName();
}
if($modelName === ''){
//如果指定了为空字符串,直接把key当属性名赋值value套到自己的属性里
foreach($data as $key => $value){
$this->{$key} = $value;
}
return true;
}elseif(isset($data[$modelName])){
//如果模型名字比如 UserForm 这个key在data里的话,那就遍历这个key下面的属性进行赋值
foreach($data[$modelName] as $key => $value){
$this->{$key} = $value;
}
return true;
}else{
return false;
}
}
}
自定义表单要load成功通常得传第2个参数为空字符串 ¶
很经常大家都是自己构造表单的,毕竟ActiveForm满足不了各种需求,甚至一些ajax的前端数据构造逻辑更加直接,前端人员想都没想到要加模型名字包一层对象
现象大概就是这样的:
$post = [
'name' => 'aaa',
'age' => 11,
];
$model = new UserForm();
$model->load($post);
根据上面的解析,如果第2个参数为默认的null,则load里面会自动获取模型的短类名得到UserForm
,然后企图从$data['UserForm']
里取得要被load的数据
结果实际上传进去的$post数组在第1层key并不包含UserForm,结果就导致了load失败
在这种情况下要让load的时候直接取$post的key套到模型的属性里,那很简单,就是传入第二个参数为空字符串,一定要是空字符串:
$post = [
'name' => 'aaa',
'age' => 11,
];
$model = new UserForm();
$model->load($post, ''); //!!!重点!!!
load失败后是不会有error的 ¶
所以如果企图在load返回false的时候打印$model->errors
那是不会有东西的
load失败代表的就是这个过程中它无法从$data参数中得到任何可以load的数据,所以如果此时要向客户端报错,我觉得大概应该将提示信息人工设置为“接收参数失败”
有兴趣的话请稳步到此阅读《正确地设定load失败的提示信息》