## 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(); ?>
```
#### 訪問預覽

> 不同的控制器調用不同的**模型場景**,對數據進行校驗。
### 使用場景進行屬性塊賦值
使用場景進行屬性塊賦值只是在賦值給模塊的`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]);
}
}
```
#### 查看視圖結果

> 訪問`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]);
}
}
```
#### 查看效果

> 訪問`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上傳插件