Yii2 - 场景(应用与设置)

作者:zheng_Great 2020-03-27 2780次

原文链接:

1:https://www.yii-china.com/doc/detail/20

2:https://www.yiichina.com/tutorial/89 (推荐)

3:https://www.imooc.com/article/13668


场景

模型可能在多个 场景 下使用,例如 User 模块可能会在收集用户登录输入, 也可能会在用户注册时使用。在不同的场景下, 模型可能会使用不同的业务规则和逻辑, 例如 email 属性在注册时强制要求有,但在登陆时不需要。

模型使用 yii\base\Model::scenario 属性保持使用场景的跟踪, 默认情况下,模型支持一个名为 default 的场景, 如下展示两种设置场景的方法:

// 场景作为属性来设置
$model = new User;
$model->scenario = 'login';

// 场景通过构造初始化配置来设置
$model = new User(['scenario' => 'login']);

默认情况下,模型支持的场景由模型中申明的 验证规则 来决定, 但你可以通过覆盖yii\base\Model::scenarios()方法来自定义行为, 如下所示:

namespace app\models;use yii\db\ActiveRecord;
class User extends ActiveRecord
{    
    const SCENARIO_LOGIN = 'login';    
    const SCENARIO_REGISTER = 'register';    
    
    public function scenarios()
    {        
        return [            
            self::SCENARIO_LOGIN => ['username', 'password'], 
            self::SCENARIO_REGISTER => ['username', 'email', 'password'],
        ];
    }
}

Info:在上述和下述的例子中,模型类都是继承yii\db\ActiveRecord, 因为多场景的使用通常发生在Active Record类中.

scenarios() 方法返回一个数组,数组的键为场景名,值为对应的 active attributes活动属性。 活动属性可被 块赋值并遵循验证规则 在上述例子中,username 和 password 在login场景中启用,在 register 场景中, 除了 username and password 外 email 也被启用。

scenarios() 方法默认实现会返回所有yii\base\Model::rules()方法申明的验证规则中的场景, 当覆盖scenarios()时,如果你想在默认场景外使用新场景, 可以编写类似如下代码:

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;
    }
}

场景特性主要在验证 和 属性块赋值 中使用。 你也可以用于其他目的, 例如可基于不同的场景定义不同的 属性标签


验证规则

当模型接收到终端用户输入的数据, 数据应当满足某种规则(称为 验证规则, 也称为 业务规则)。 例如假定ContactForm模型,你可能想确保所有属性不为空且 email 属性包含一个有效的邮箱地址, 如果某个属性的值不满足对应的业务规则, 相应的错误信息应显示,以帮助用户修正错误。

可调用 yii\base\Model::validate() 来验证接收到的数据, 该方法使用yii\base\Model::rules()申明的验证规则来验证每个相关属性, 如果没有找到错误,会返回 true, 否则它会将错误保存在 yii\base\Model::errors 属性中并返回false,例如:

$model = new \app\models\ContactForm;

// 用户输入数据赋值到模型属性
$model->attributes = \Yii::$app->request->post('ContactForm');

if ($model->validate()) {    
    // 所有输入数据都有效 all inputs are valid
} 
else {    
    // 验证失败:$errors 是一个包含错误信息的数组
    $errors = $model->errors;
}

通过覆盖 yii\base\Model::rules() 方法指定模型 属性应该满足的规则来申明模型相关验证规则。 下述例子显示ContactForm模型申明的验证规则:

public function rules()
{
    return [
        // name, email, subject 和 body 属性必须有值
        [['name', 'email', 'subject', 'body'], 'required'],        
        
        // email 属性必须是一个有效的电子邮箱地址
        ['email', 'email'],
    ];
}

一条规则可用来验证一个或多个属性,一个属性可对应一条或多条规则。 更多关于如何申明验证规则的详情请参考 验证输入 一节.

有时你想一条规则只在某个 场景 下应用,为此你可以指定规则的 on 属性, 如下所示:

public function rules()
{
    return [
        // 在"register" 场景下 username, email 和 password 必须有值
        [['username', 'email', 'password'], 'required', 'on' => 'register'],
        
        // 在 "login" 场景下 username 和 password 必须有值
        [['username', 'password'], 'required', 'on' => 'login'],
    ];
}

如果没有指定 on 属性,规则会在所有场景下应用, 在当前yii\base\Model::scenario 下应用的规则称之为 active rule活动规则

一个属性只会属于scenarios()中定义的活动属性且在rules() 申明对应一条或多条活动规则的情况下被验证。