Model
模型是MVC模式中的一部分,是代表业务数据、规则和逻辑对象
默认情况下你的模型类直接从yii\base\Model
继承,所有非静态公有成员变量都是属性。
例如,下述ContactForm
模型类有4个属性name,email,subject,content
,
ContactForm
模型用来代表从HTML表单获取的输入数据。
namespace app\models;
use yii\base\Model;
class ContactForm extends Model
{
public $name;
public $email;
public $subject;
public $content;
}
验证
当模型接收到终端用户输入的数据,数据应该满足某种规则(称为验证规则,也称为业务规则)。
通过覆盖yii\base\Model::rules()
方法指定模型属性应该满足的规则来申明模型相关验证规则。
下述例子显示ContactForm
模型声明的验证规则:
public function rules()
{
return [
//username,email,subject,content属性必须有值
[['username','email','subject','content'],'required'],
['email','email'], //email必须是邮箱格式
];
}
控制器里验证
$model = new \app\models\ContactForm();
if($model->validate()){
// 验证通过
}else{
// 验证没有通过
}
场景
模型可能在多个场景
下使用,例如User
模型可能会收集用户登录输入,也可能会在用户注册时用户。
在不同的场景下,模型可能会使用不同的业务规则和逻辑,例如email
属性在注册时强制要求有,但在登录时不需要。
模型使用yii\base\Model::scenario
属性保持使用场景跟踪,
默认情况下,模型支持一个名为default
的场景,如下展示两种场景的方法:
// 场景作为属性来设置
$model = new User();
$model->scenario = 'login';
// 场景通过构造初始化配置来设置
$model = new User(['scenario'=>'login'])
有时你想一条规则只在某个场景
下应用,为此你可以执行规则的on
属性,如下所示:
// 验证规则
public function rules()
{
return [
// 在'register'场景下 username,email,password属性必须有值
[['username','email','password'],'required','on'=>'register'],
// 在'login'场景下 username,password属性必须有值
[['username','password'],'required','on'=>'login'],
];
}
模型最佳实践
模型是代表业务数据、规则和逻辑的中心地方,通常很多地方重用,
在一个设计良好的应用中,模型通常比控制器代码多。
归纳起来,模型:
可包含属性来展示业务数据;
可包含验证规则确保数据有效和完整;
可包含方法实现业务逻辑;
不应直接访问请求,session和其他环境数据,这些应该由`控制器`传入到模型;
应避免嵌入HTML或其他展示代码,这些代码最好在`视图`中处理;
单个模型中避免太多`场景`。
在开发大型复杂系统时经常考虑最后一条建议,
在这些系统中,模型会很大并在很多地方使用,因此包含需要规则集和业务逻辑,
最后维护这些模型代码成为一个噩梦,因为一个简单修改会影响很多地方。
为了确保模型的易维护性,最好使用以下策略:
定义可被多个`application(应用)`或`module(模块)`共享的模型基类,这些模型应包含通用的最小规则集合和逻辑。
在每个使用模型的[应用]和[模块]中,通过继承对应的模型基类来定义具体的模型类,具体模型类包含应用主体或模型指定的规则和逻辑。
例如,在[高级应用模板],你可以定义一个模型基类common\models\Post
,
然后在前台应用中,定义并使用一个继承common\models\Post
的具体模型类frontend\models\Post
,
在后台应用中可以类似的定义backend\models\Post
。
通过这种策略,你清楚frontend\models\Post
只对应前台应用,如果你修改它,就无需担心修改会影响后台应用。
示例
1、新建models\Member.php
<?php
namespace app\models;
use yii\base\Model;
class Member extends Model
{
public $username;
public $email;
// 验证规则
public function rules()
{
return [
// username,email属性必须有值
[['username','email'],'required','on'=>'register'],
// email必须是邮箱格式
['email','email']
];
}
}
2、控制器里使用模型
public function actionIndex()
{
$member = new Member();
$member->scenario = 'register';
$member->email = 'a@b.c';
$member->username = 'Lily';
// 验证是否合法
if($member->validate()){
return 'ok';
}else{
// 打印验证未通过的原因信息
var_dump($member->getFirstErrors());
}
}