模型是 MVC 模式中的一部分, 是代表业务数据、规则和逻辑的对象。
模型是 CModel 或其子类的实例。模型用于保持数据以及与其相关的业务逻辑。
模型是单独的数据对象。它可以是数据表中的一行,或者一个用户输入的表单。 数据对象的每个字段对应模型中的一个属性。每个属性有一个标签(label), 并且可以通过一系列规则进行验证。
Yii 实现了两种类型的模型:表单模型和 Active Record。二者均继承于相同的基类 CModel。
表单模型是 CFormModel 的实例。表单模型用于保持从用户的输入获取的数据。 这些数据经常被获取,使用,然后丢弃。例如,在一个登录页面中, 我们可以使用表单模型用于表示由最终用户提供的用户名和密码信息。
Active Record (AR) 是一种用于通过面向对象的风格抽象化数据库访问的设计模式。 每个 AR 对象是一个 CActiveRecord 或其子类的实例。代表数据表中的一行。 行中的字段对应 AR 对象中的属性。
可通过继承 yii\base\Model 或它的子类定义模型类,基类yii\base\Model支持许多实用的特性:
属性: 代表可像普通类属性或数组一样被访问的业务数据;
属性标签: 指定属性显示出来的标签;
块赋值: 支持一步给许多属性赋值;
验证规则: 确保输入数据符合所申明的验证规则;
数据导出: 允许模型数据导出为自定义格式的数组。
属性
模型通过 属性 来代表业务数据,每个属性像是模型的公有可访问属性, yii\base\Model::attributes() 指定模型所拥有的属性。
可像访问一个对象属性一样访问模型的属性:
$model = new \app\models\ContactForm; // "name" 是ContactForm模型的属性 $model->name = 'example'; echo $model->name;
也可像访问数组单元项一样访问属性,这要感谢yii\base\Model支持 ArrayAccess 数组访问 和 ArrayIterator 数组迭代器:
$model = new \app\models\ContactForm; // 像访问数组单元项一样访问属性 $model['name'] = 'example'; echo $model['name']; // 迭代器遍历模型 foreach ($model as $name => $value) { echo "$name: $value\n"; }
定义属性
默认情况下你的模型类直接从yii\base\Model继承,所有 non-static public非静态公有 成员变量都是属性。 例如,下述ContactForm模型类有四个属性name, email, subject and body, ContactForm 模型用来代表从HTML表单获取的输入数据。
namespace app\models; use yii\base\Model; class ContactForm extends Model { public $name; public $email; public $subject; public $body; }
另一种方式是可覆盖 yii\base\Model::attributes() 来定义属性,该方法返回模型的属性名。 例如 yii\db\ActiveRecord 返回对应数据表列名作为它的属性名, 注意可能需要覆盖魔术方法如__get(), __set()使属性像普通对象属性被访问。
属性标签
当属性显示或获取输入时,经常要显示属性相关标签,例如假定一个属性名为firstName, 在某些地方如表单输入或错误信息处,你可能想显示对终端用户来说更友好的 First Name 标签。
可以调用 yii\base\Model::getAttributeLabel() 获取属性的标签,例如:
$model = new \app\models\ContactForm; // 显示为 "Name" echo $model->getAttributeLabel('name');
默认情况下,属性标签通过yii\base\Model::generateAttributeLabel()方法自动从属性名生成. 它会自动将驼峰式大小写变量名转换为多个首字母大写的单词,例如 username 转换为 Username, firstName 转换为 First Name。
如果你不想用自动生成的标签,可以覆盖 yii\base\Model::attributeLabels() 方法明确指定属性标签,例如:
namespace app\models; use yii\base\Model; class ContactForm extends Model { public $name; public $email; public $subject; public $body; public function attributeLabels() { return [ 'name' => 'Your name', 'email' => 'Your email address', 'subject' => 'Subject', 'body' => 'Content', ]; } }
应用支持多语言的情况下,可翻译属性标签, 可在 yii\base\Model::attributeLabels() 方法中定义,如下所示:
public function attributeLabels() { return [ 'name' => \Yii::t('app', 'Your name'), 'email' => \Yii::t('app', 'Your email address'), 'subject' => \Yii::t('app', 'Subject'), 'body' => \Yii::t('app', 'Content'), ]; }
甚至可以根据条件定义标签,例如通过使用模型的 scenario场景, 可对相同的属性返回不同的标签。
补充:属性标签是 视图一部分,但是在模型中申明标签通常非常方便,并可行程非常简洁可重用代码。
场景