·您现在的位置: 云翼网络 >> 文章中心 >> 网站建设 >> 网站建设开发 >> php网站开发 >> Yii2Guide-3.6-Models

Yii2Guide-3.6-Models

作者:佚名      php网站开发编辑:admin      更新时间:2022-07-23
Yii2Guide-3.6-Models

models是展示业务数据、规则和逻辑的对象。

你可以通过扩展yii\base\Model或者其子类来创建model类, 这个基类支持下面的特性:

  • Attributes

    • 展示业务数据,可以像访问正常的对象属性或者数组元素一样来访问
  • Attribute labels

    • 为属性指定显示的label
  • Massive assignment

    • 支持一步激活多个属性的值
  • Validation rules

    • 确保输入的数据符合声明的验证规则
  • Data Exporting

    • 允许模型的数据根据自定义的格式数组导出

Model Class还是某些更复杂的模型的基类,比如Active Record

原创文章, 转载请注明 http://www.cnblogs.com/ganiks/

并没有强制说你一定要让你的模型类基于yii\base\Model,但是因为有很多的Yii的组件都是支持yii\base\Model的, 建议你还是基于它来构建你的模型。

3.6.1 Attributes访问属性

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\ModelArrayaccessArrayIterator的支持。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']    ];}

一个属性要想被validate(), 需要符合2个条件, 它在scenarios()中被声明为active attribute; 跟rules()中声明的一个或者多个active rules相关联另外, 如果属性没有自定on,则默认是适用于所有的场景

3.6.4 Massive Assignment

批量赋值,是一个方便的方法,可以用一行代码就让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()有两个目的:

  1. 决定哪些属性要被validate
  2. 决定哪些属性是safe

而有些极少数的情况下, 你可能想要validate一个属性而并不想让其safe

public function scenarios(){    return [        'login' => ['username', 'password', '!secret'],    ];}
3.6.5 Data Exporting

模型经常需要被导出为不同的格式。比如你可能想要将一系列的模型转换到JSON或者Excel。

导出过程可以分为2步:

  1. models->arrays
  2. arrays->json/excel...

第二步很简单,可以通过类似实现yii\web\JsonResponseFormatter;主要是第一步, 最简单的方法是yii\base\Model::attributes

$post = \app\models\Post::findOne(100);$array = $post->attributes;

还有一个更复杂的方法(用于RESTful API)中, 叫做 yii\base\Model::toArray(), 这个方法强大之处在于, 允许你决定最终的结果中包含哪些项目,叫做fileds,并且可以指定如何format

关于fields
public 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;}