models是展示业务数据、规则和逻辑的对象。
你可以通过扩展yii/base/Model或者其子类来创建model类, 这个基类支持下面的特性:
Attributes
Attribute labels
Massive assignment
Validation rules
Data Exporting
Model Class还是某些更复杂的模型的基类,比如Active Record
原创文章, 转载请注明 http://www.VEVb.com/ganiks/
3.6.1 Attributes访问属性并没有强制说你一定要让你的模型类基于
yii/base/Model,但是因为有很多的Yii的组件都是支持yii/base/Model的, 建议你还是基于它来构建你的模型。
yii/base/Model::attributes()制定了这个模型类含有哪些属性, 访问其属性如下:
$model = new /app/models/ContactForm;$model->name = 'example';echo $model->name;也可以如下访问属性:
$model = new /app/models/ContactForm;$model['name'] = 'example';echo $model['name'];foreach($model as $name=>$value){ echo "$name:$value/n";}这要多谢 yii/base/Model对Arrayaccess和ArrayIterator的支持。http://php.net/manual/en/class.arrayaccess.phphttp://php.net/manual/en/class.arrayiterator.php
默认的, 如果你的 model直接扩展自yii/base/Model, 那么它所有的 non-static public 成员都是属性。例如,下面这个就有4个属性。
namespace app/models;use yii/base/Model;class ContactForm extends Model{ public $name; public $email; public $subject; public $body;}你也可以通过定义yii/base/Model::attributes()方法来定义属性, 但是通常不这样做,即使在ActiveRecord中,也常常是用tableName()来直接返回一个表名。
public static function tableName() { return '{{%user}}'; }属性标签$model = new /app/models/ContactForm;echo $model->getAttributeLabel('name');默认的, 这些labes是由方法yii/base/Model::generateAttributeLabel()自动生成, 经过转换 ,firstName=>First Name
你也可以自定义:
public function attributeLabels() { return [ 'name' => 'Your name', 'email' => 'Your email address', 'subject' => /Yii::t('app', 'Subject'), ]; }3.6.2 Scenarios场景是个很有用的东西,能够让一个model在不同的情况下灵活使用。
举例来说, 一个User模型可能用于采集用户登录的输入,也可以用于注册。在不同的情况下, 一个模型可能使用不同的业务和逻辑。比如,email属性可能在用户注册时候才是必填的。
模型使用属性yii/base/Model::scenario来记载目前所处的场景。默认的, 用的是一个default场景。
下面是两种设置场景的方式:
$model = new User;$model->scenario = 'login';$model = new User(['scenario' => 'login']);默认的, 一个模型支持的场景是由其validataion rules中声明的。但是,你也可以通过重写下面的方法来自定义这个行为:
class User extends ActiveRecord{ public function scenarios() { return [ 'login' => ['username', 'passWord'], 'register' => ['username', 'email', 'password'] ]; }}多场景的模型多用于
ActiveRecord类模型。
scenarios()方法返回的是一个数组,键是场景名字,值则是相应的active attributes。
默认的像上面这样的scenarios()返回的是在yii/base/Model::rules()中声明的验证规则中的所有的场景;而如果你要引入新的场景,则应该这样做:
class User extends ActiveRecord{ public function scenarios() { $scenarios = parent::scenarios(); $scenarios['login'] = ['username', 'password']; ... return $scenarios; }}场景这个特性,主要用于“验证”和“批零赋值”,也可以用于“指定labels”
3.6.3 Validation Rules调用validate
yii/base/Model::validate()if($model->validate()){ ...}声明validation rules
yii/base/Model::rules()public function rules(){ return [ [['name', 'email', 'subject', 'body'], 'required', 'on' => 'register'], ['email', 'email'] ];}3.6.4 Massive Assignment一个属性要想被validate(), 需要符合2个条件, 它在
scenarios()中被声明为active attribute; 跟rules()中声明的一个或者多个active rules相关联另外, 如果属性没有自定on,则默认是适用于所有的场景
批量赋值,是一个方便的方法,可以用一行代码就让model跟用户的输入结合起来。它直接的把用户的输入赋给了yii/base/Model::attributes属性。
下面是两种方式,很明显, 前者更简洁:
$model = new ContactForm;$model->attributes = Yii::$app->request->post('ContactForm');$model = new ContactForm;$data = Yii::$app->request->post('ContactForm', []);$model->name = iseet($data['name']) ? $data['name'] : null ;... ...... ...Safe Attributes 安全属性批量赋值,只作用于所谓的“安全属性”, 也就是在yii/base/Model::scenarios()中列出的属性;而其他的属性则不会有所动。
安全属性这个特性的好处在于,方便你控制那些属性可以被终端用户操作。
由于默认的yii/base/Model::scenarios()会返回yii/base/Model::rules()中所有的场景和属性,如果你重写这个方法,意味着只要出现在rules()中的属性,就都是安全属性。那如果我想要的安全属性并不需要定义什么验证规则怎么办呢?基于这个原因,yii提供了safe来让你单独声明安全属性的规则
public function rules(){ return [ [['title', 'description'], 'safe'], ];}Unsafe Attributes 非安全属性如上所述, yii/base/Model::scenarios()有两个目的:
而有些极少数的情况下, 你可能想要validate一个属性而并不想让其safe
public function scenarios(){ return [ 'login' => ['username', 'password', '!secret'], ];}3.6.5 Data Exporting模型经常需要被导出为不同的格式。比如你可能想要将一系列的模型转换到JSON或者Excel。
导出过程可以分为2步:
第二步很简单,可以通过类似实现yii/web/JsonResponseFormatter;主要是第一步, 最简单的方法是yii/base/Model::attributes
$post = /app/models/Post::findOne(100);$array = $post->attributes;还有一个更复杂的方法(用于RESTful API)中, 叫做 yii/base/Model::toArray(), 这个方法强大之处在于, 允许你决定最终的结果中包含哪些项目,叫做fileds,并且可以指定如何format
fieldspublic function fields(){ return [ 'id', 'email' => 'email_address', 'name' => function(){ return $this->first_name.' '. $this->last_name; } ];}public function fields(){ $fields = parent::fields(); unset($fields['auth_key'], $fields['password_hash']); return $fields;}新闻热点
疑难解答