## Yii2模型中的场景
[TOC]
在不同的场景下,模型可能会使用不同的业务规则和逻辑, 例如`email`属性在注册时强制要求有,但在登陆时不需要;也就是说`User`模型可能会在收集用户登录输入, 也可能会在用户注册时使用验证。
场景特性主要在**验证**、**属性块赋值**或者**基于不同的场景定义不同的 属性标签**。
### 使用场景进行验证
#### 定义模型验证规则
文件在`app\models\Users.php`内容如下:
```php
<?php
namespace app\models;
use yii\db\ActiveRecord;
class Users extends ActiveRecord
{
const SCENARIO_LOGIN = 'login';
const SCENARIO_REGISTER = 'register';
/**
* @return string
*/
public static function tableName()
{
return 'users';
}
public function rules()
{
return [
// 在"register" 场景下 username, email 和 password 必须有值
[['username', 'email', 'password'], 'required', 'on' => self::SCENARIO_REGISTER],
// 在 "login" 场景下 username 和 password 必须有值
[['username', 'password'], 'required', 'on' => self::SCENARIO_LOGIN],
];
}
}
```
#### 在控制器中使用
文件在`app\controllers\UserController.php`内容如下:
```php
<?php
namespace app\controllers;
use app\models\Users;
use yii\web\Controller;
class UserController extends Controller
{
public function actionLogin()
{
$model = new Users;
$model->scenario = Users::SCENARIO_LOGIN;
// 或者通过构造函数配置 $model = new Users(['scenario'=>'login']);
if (\Yii::$app->request->isPost) {
}
return $this->render('login', ['model' => $model]);
}
public function actionRegister()
{
$model = new Users(['scenario'=>'register']);
if (\Yii::$app->request->isPost) {
}
return $this->render('login', ['model' => $model]);
}
}
```
#### 视图文件
文件在`app\views\user\login.php`内容如下:
```html
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
?>
<?php $form = ActiveForm::begin(['id' => 'contact-form']); ?>
<?= $form->field($model, 'username')->textInput(['autofocus' => true]) ?>
<?= $form->field($model, 'email') ?>
<?= $form->field($model, 'password')->passwordInput() ?>
<div class="form-group">
<?= Html::submitButton('Submit', ['class' => 'btn btn-primary', 'name' => 'contact-button']) ?>
</div>
<?php ActiveForm::end(); ?>
```
#### 访问预览
![](https://box.kancloud.cn/898ad73c868acd446f765ff8a901539a_1223x446.png)
> 不同的控制器调用不同的**模型场景**,对数据进行校验。
### 使用场景进行属性块赋值
使用场景进行属性块赋值只是在赋值给模块的`attributes`属性赋值的时候会根据定义的规则进行赋值。
#### 定义模型场景规则
文件在`app\models\Users.php`内容如下:
```php
<?php
namespace app\models;
use yii\db\ActiveRecord;
class Users extends ActiveRecord
{
const SCENARIO_LOGIN = 'login';
const SCENARIO_REGISTER = 'register';
/**
* @return string
*/
public static function tableName()
{
return 'users';
}
/**
* @return array
*/
public function scenarios()
{
$scenarios = parent::scenarios();
$scenarios[self::SCENARIO_LOGIN] = ['username', 'password'];
$scenarios[self::SCENARIO_REGISTER] = ['username', 'email', 'password'];
return $scenarios;
}
}
```
#### 控制器代码
```php
<?php
namespace app\controllers;
use app\models\Users;
use yii\web\Controller;
class UserController extends Controller
{
public function actionLogin()
{
$model = new Users;
$model->scenario = Users::SCENARIO_LOGIN;
// 或者通过构造函数配置 $model = new Users(['scenario'=>'login']);
if (\Yii::$app->request->isPost) {
$model->attributes = \Yii::$app->request->post('Users');
print_r($model); // 查看model的属性只有"username"和"password"被赋值
}
return $this->render('login', ['model' => $model]);
}
public function actionRegister()
{
$model = new Users(['scenario'=>'register']);
if (\Yii::$app->request->isPost) {
$model->attributes = \Yii::$app->request->post('Users');
print_r($model);// 查看model的属性只有"username","email"和"password"被赋值
}
return $this->render('login', ['model' => $model]);
}
}
```
#### 查看视图结果
![](https://box.kancloud.cn/4af648836112abbfd1b8112695e4fec4_1269x226.png)
> 访问`login()`操作,得到的是模型中定义的`login`场景限制的字段'username', 'password'。
访问`register()`操作,得到的是模型中定义的`register`场景限制的字段'username', 'email', 'password'。
### 使用场景定义不同的属性标签
属性标签是 视图一部分,但是在模型中申明标签通常非常方便, 并可形成非常简洁可重用代码。
#### 定义模型规则
文件在`app\models\Users.php`内容如下(主要查看`attributeLabels()`方法):
```php
<?php
namespace app\models;
use yii\db\ActiveRecord;
class Users extends ActiveRecord
{
const SCENARIO_LOGIN = 'login';
const SCENARIO_REGISTER = 'register';
/**
* @return string
*/
public static function tableName()
{
return 'users';
}
/**
* @return array
*/
public function attributeLabels()
{
if ($this->scenario == self::SCENARIO_LOGIN) {
$typeString = '登录';
$userName = $typeString . '用户名';
$email = $typeString . '邮箱';
$password = $typeString . '密码';
} else {
$typeString = '注册';
$userName = $typeString . '名';
$email = $typeString . '邮箱';
$password = $typeString . '密码';
}
return [
'username' => $userName,
'email' => $email,
'password' => $password,
];
}
}
```
#### 控制器使用`render()`方法渲染模板文件
```php
<?php
namespace app\controllers;
use yii\web\Controller;
class UserController extends Controller
{
public function actionLogin()
{
return $this->render('login', ['model' => $model]);
}
public function actionRegister()
{
return $this->render('login', ['model' => $model]);
}
}
```
#### 查看效果
![](https://box.kancloud.cn/e4b9be880bb6c5c785291575e64bc8b7_1594x382.png)
> 访问`register()`操作和`login()`操作相应的提示字段变成自定义的。
- 开始
- Yii2开发小技巧
- Yii2使用不同的方式进行邮件发送逻辑处理
- Yii2 Serialization of 'Closure' is not allowed 错误
- Yii创建应用
- Yii应用结构和流程
- Yii的路径别名
- Yii的请求
- Yii的响应
- Sessions 和 Cookies
- Yii自定义全局工具函数
- Yii2模型
- Yii2视图
- Yii2控制器
- 大数据节省内存处理
- 关联查询hasMany、hasOne
- Yii2 URL地址美化
- Yii2整合AdminLTE后台主题
- Yii2模型中的场景
- Yii2中的RBAC
- Yii2项目后台整合yii2-admin模块
- RBAC集成AdminLTE后台主题对菜单进行控制
- Yii2自定义Gii模板
- 修复AdminLTE引用外部字体文件导致访问变慢的情况
- Yii2事件简单使用
- Yii2模型事件
- Yii2使用GridView新增操作按钮
- Yii2向loyout模板文件中传值
- Yii2数据缓存
- Yii2缓存
- Yii2数据缓存之增删改查
- Yii2拓展
- Yii2日期时间插件-datetimepicker
- kartik-v/yii2-widget-fileinput上传插件