携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情
模型
- 模型是 MVC 模式中的一部分, 是代表业务数据、规则和逻辑的对象
- 可通过继承 yii\base\Model 或它的子类定义模型类, 基类yii\base\Model支持许多实用的特性
- 模型是代表业务数据、规则和逻辑的中心地方,通常在很多地方重用, 在一个设计良好的应用中,模型通常比 控制器代码多.
- 可包含属性来展示业务数据;
- 可包含验证规则确保数据有效和完整;
- 可包含方法实现业务逻辑;
- 不应直接访问请求,session和其他环境数据, 这些数据应该由控制器传入到模型;
- 应避免嵌入HTML或其他展示代码,这些代码最好在 视图中处理;
- 单个模型中避免太多的 场景.
属性
模型通过 属性 来代表业务数据,每个属性像是模型的公有可访问属性, yii\base\Model::attributes() 指定模型所拥有的属性.
可像访问一个对象属性一样访问模型的属性,也可像访问数组单元项一样访问属性
代表可像普通类属性或数组 一样被访问的业务数据;
-
定义属性
namespace app\models; use yii\base\Model; class ContactForm extends Model { public $name; public $email; public $subject; public $body; } -
属性标签
namespace app\models; use yii\base\Model; class ContactForm extends Model { public $name; public $email; public $subject; public $body; public function attributeLabels() { return [ 'name' => 'Your name', 'email' => 'Your email address', 'subject' => 'Subject', 'body' => 'Content', ]; } //如果应用支持多语言的情况下 public function attributeLabels() { return [ 'name' => \Yii::t('app', 'Your name'), 'email' => \Yii::t('app', 'Your email address'), 'subject' => \Yii::t('app', 'Subject'), 'body' => \Yii::t('app', 'Content'), ]; } }
场景
不同的场景下模型中使用不同的业务规则和逻辑
两种设置场景的方法
// 场景作为属性来设置
$model = new User;
$model->scenario = 'login';
// 场景通过构造初始化配置来设置
$model = new User(['scenario' => 'login']);
namespace app\models;
use yii\db\ActiveRecord;
class User extends ActiveRecord
{
const SCENARIO_LOGIN = 'login';
const SCENARIO_REGISTER = 'register';
public function scenarios()
{
$scenarios = parent::scenarios();
$scenarios[self::SCENARIO_LOGIN] = ['username', 'password'];
$scenarios[self::SCENARIO_REGISTER] = ['username', 'email', 'password'];
return $scenarios;
}
}
验证规则
当模型接收到终端用户输入的数据, 数据应当满足某种规则(称为 验证规则, 也称为 业务规则)
可调用 yii\base\Model::validate() 来验证接收到的数据, 该方法使用yii\base\Model::rules()申明的验证规则来验证每个相关属性,如果没有找到错误,会返回 true, 否则它会将错误保存在 yii\base\Model::errors 属性中并返回false
//controller.php
$model = new \app\models\ContactForm;
// 用户输入数据赋值到模型属性
$model->attributes = \Yii::$app->request->post('ContactForm');
if ($model->validate()) {
// 所有输入数据都有效 all inputs are valid
} else {
// 验证失败: $errors 是一个包含错误信息的数组
$errors = $model->errors;
}
//models.php
//如果没有指定 on 属性,规则会在所有场景下应用
public function rules()
{
return [
// 在"register" 场景下 username, email 和 password 必须有值
[['username', 'email', 'password'], 'required', 'on' => 'register'],
// 在 "login" 场景下 username 和 password 必须有值
[['username', 'password'], 'required', 'on' => 'login'],
];
}
块赋值
块赋值只用一行代码将用户所有输入填充到一个模型,非常方便, 它直接将输入数据对应填充到 yii\base\Model::attributes() 属性
//写法1
$model = new \app\models\ContactForm;
$model->attributes = \Yii::$app->request->post('ContactForm');
//写法2
$model = new \app\models\ContactForm;
$data = \Yii::$app->request->post('ContactForm', []);
$model->name = isset($data['name']) ? $data['name'] : null;
$model->email = isset($data['email']) ? $data['email'] : null;
$model->subject = isset($data['subject']) ? $data['subject'] : null;
$model->body = isset($data['body']) ? $data['body'] : null;
安全属性
块赋值只应用在安全属性上
只要出现在活动验证规则中的属性都是安全的.
非安全属性
//yii\base\Model::scenarios() 方法提供两个用处: 定义哪些属性应被验证,定义哪些属性安全
public function scenarios()
{
return [
//username,password可以被块赋值,secret则需要明确赋值($model->secret = $secret;)
'login' => ['username', 'password', '!secret'],
];
}
字段
通过覆盖 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;
}