数据导出
模型通常要导出成不同格式,例如,你可能想将模型的一个集合转成JSON或Excel格式, 导出过程可分解为两个步骤:
- 模型转换成数组;
- 数组转换成所需要的格式。
你只需要关注第一步,因为第二步可被通用的 数据转换器如yii\web\JsonResponseFormatter来完成。
将模型转换为数组最简单的方式是使用 yii\base\Model::attributes() 属性, 例如:
$post = \app\models\Post::findOne(100);
$array = $post->attributes;
yii\base\Model::attributes() 属性会返回 Model里所有 申明的属性的值(model表对应的所有字段)。
更灵活和强大的将模型转换为数组的方式是使用 yii\\base\\Model::toArray()
方法, 它的行为默认和 yii\\base\\Model::attributes()
相同, 但是它允许你选择哪些称之为_字段_的数据项放入到结果数组中并同时被格式化。 实际上,它是导出模型到 RESTful 网页服务开发的默认方法, 详情请参阅响应格式.
字段
字段是模型通过调用 yii\\base\\Model::toArray()
生成的数组的单元名。
默认情况下,字段名对应属性名,但是你可以通过覆盖 fields()
和 extraFields()
方法来改变这种行为, 两个方法都返回一个字段定义列表,fields()
方法定义的字段是默认字段, 表示toArray()
方法默认会返回这些字段。 extraFields()
方法定义额外可用字段, 通过toArray()
方法指定$expand
参数来返回这些额外可用字段。 例如如下代码会返回fields()
方法定义的所有字段和extraFields()
方法定义的prettyName
and fullAddress
字段。
$array = $model->toArray([], ['prettyName', 'fullAddress']);
可通过覆盖 fields()
来增加、删除、重命名和重定义字段, fields()
方法返回值应为数组, 数组的键为字段名,数组的值为对应的可为属性名或匿名函数返回的字段定义对应的值。 特使情况下,如果字段名和属性定义名相同,可以省略数组键, 例如:
// 明确列出每个字段,特别用于你想确保数据表或模型
// 属性改变不会导致你的字段改变(保证后端的API兼容)。
public function fields()
{
return [
// 字段名和属性名相同
'id',
// 字段名为 "email",对应属性名为 "email_address"
'email' => 'email_address',
// 字段名为 "name", 值通过PHP代码返回
'name' => function () {
return $this->first_name . ' ' . $this->last_name;
},
];
}
// 过滤掉一些字段,特别用于
// 你想继承父类实现并不想用一些敏感字段
public function fields()
{
$fields = parent::fields();
// 去掉一些包含敏感信息的字段
unset($fields['auth_key'], $fields['password_hash'], $fields['password_reset_token']);
return $fields;
}
**警告: **由于模型的所有属性会被包含在导出数组,最好检查数据确保没包含敏感数据, 如果有敏感数据,应覆盖
fields()
方法过滤掉, 在上述列子中,我们选择过滤掉auth_key
,password_hash
andpassword_reset_token
。
实例
返回指定的字段:id, app_tile , app_mark, project_id
其中 app_tile 在model模型中的属性为 title
### 控制器
$model = VbbTask::findOne(1380);
$model->toArray([], ['project_id']);
### model重写 fields, extraFields
public function fields()
{
if (\Yii::$app->getRequest()->getIsPost()) {
return [
'id', //段名和属性名相同
'sub_titile' => 'title',// 字段名为 "sub_titile",对应属性名为 "title"
'app_mark' => function() {
return '这里函数处理后的返回值';
},
'nickname' => function() {
//给昵称加前缀 nick_,返回给客户端
$post = \Yii::$app->getRequest()->post();
return 'nick_' . $post['nickname'];
},
} else {
return parent::fields();
}
public function extraFields()
{
return [
'project_id',
];
}
需要对返回的字段名,或者返回值做二次处理,就可以用以上的方法