PHP的Yii框架中Model模型的学习教程
|
模型是 MVC 模式中的一部分, 是代表业务数据、规则和逻辑的对象。 模型是 CModel 或其子类的实例。模型用于保持数据以及与其相关的业务逻辑。 模型是单独的数据对象。它可以是数据表中的一行,或者一个用户输入的表单。 数据对象的每个字段对应模型中的一个属性。每个属性有一个标签(label), 并且可以通过一系列规则进行验证。 Yii 实现了两种类型的模型:表单模型和 Active Record。二者均继承于相同的基类 CModel。 表单模型是 CFormModel 的实例。表单模型用于保持从用户的输入获取的数据。 这些数据经常被获取,使用,然后丢弃。例如,在一个登录页面中, 我们可以使用表单模型用于表示由最终用户提供的用户名和密码信息。 Active Record (AR) 是一种用于通过面向对象的风格抽象化数据库访问的设计模式。 每个 AR 对象是一个 CActiveRecord 或其子类的实例。代表数据表中的一行。 行中的字段对应 AR 对象中的属性。 可通过继承 yiibaseModel 或它的子类定义模型类,基类yiibaseModel支持许多实用的特性:
属性模型通过 属性 来代表业务数据,每个属性像是模型的公有可访问属性, yiibaseModel::attributes() 指定模型所拥有的属性。 可像访问一个对象属性一样访问模型的属性: // "name" 是ContactForm模型的属性$model->name = 'example'; echo $model->name; 也可像访问数组单元项一样访问属性,这要感谢yiibaseModel支持 ArrayAccess 数组访问 和 ArrayIterator 数组迭代器: // 像访问数组单元项一样访问属性$model['name'] = 'example'; echo $model['name']; // 迭代器遍历模型 定义属性默认情况下你的模型类直接从yiibaseModel继承,所有 non-static public非静态公有 成员变量都是属性。 例如,下述ContactForm模型类有四个属性name,email,subject and body, ContactForm 模型用来代表从HTML表单获取的输入数据。 use yiibaseModel;class ContactForm extends Model 另一种方式是可覆盖 yiibaseModel::attributes() 来定义属性,该方法返回模型的属性名。 例如 yiidbActiveRecord 返回对应数据表列名作为它的属性名, 注意可能需要覆盖魔术方法如__get(),__set()使属性像普通对象属性被访问。 属性标签当属性显示或获取输入时,经常要显示属性相关标签,例如假定一个属性名为firstName, 在某些地方如表单输入或错误信息处,你可能想显示对终端用户来说更友好的 First Name 标签。 可以调用 yiibaseModel::getAttributeLabel() 获取属性的标签,例如: // 显示为 "Name"echo $model->getAttributeLabel('name'); 默认情况下,属性标签通过yiibaseModel::generateAttributeLabel()方法自动从属性名生成. 它会自动将驼峰式大小写变量名转换为多个首字母大写的单词,例如 username 转换为 Username, firstName 转换为 First Name。 如果你不想用自动生成的标签,可以覆盖 yiibaseModel::attributeLabels() 方法明确指定属性标签,例如: use yiibaseModel;class ContactForm extends Model public function attributeLabels() 应用支持多语言的情况下,可翻译属性标签, 可在 yiibaseModel::attributeLabels() 方法中定义,如下所示: Yii::t('app','Your name'),'email' => Yii::t('app','Your email address'),'subject' => Yii::t('app','Subject'),'body' => Yii::t('app','Content'),]; }甚至可以根据条件定义标签,例如通过使用模型的 scenario场景, 可对相同的属性返回不同的标签。 补充:属性标签是 视图一部分,但是在模型中申明标签通常非常方便,并可行程非常简洁可重用代码。 场景模型可能在多个 场景 下使用,例如 User 模块可能会在收集用户登录输入,也可能会在用户注册时使用。 在不同的场景下,模型可能会使用不同的业务规则和逻辑,例如 email 属性在注册时强制要求有,但在登陆时不需要。 模型使用 yiibaseModel::scenario 属性保持使用场景的跟踪, 默认情况下,模型支持一个名为 default 的场景,如下展示两种设置场景的方法: scenario = 'login';// 场景通过构造初始化配置来设置 默认情况下,模型支持的场景由模型中申明的 验证规则 来决定, 但你可以通过覆盖yiibaseModel::scenarios()方法来自定义行为,如下所示: use yiidbActiveRecord;class User extends ActiveRecord 补充:在上述和下述的例子中,模型类都是继承yiidbActiveRecord, 因为多场景的使用通常发生在Active Record 类中. scenarios() 方法返回一个数组,数组的键为场景名,值为对应的 active attributes活动属性。 活动属性可被 块赋值 并遵循验证规则在上述例子中,username 和 password 在login场景中启用,在 register 场景中,除了 username and password 外 email也被启用。 scenarios() 方法默认实现会返回所有yiibaseModel::rules()方法申明的验证规则中的场景, 当覆盖scenarios()时,如果你想在默认场景外使用新场景,可以编写类似如下代码: use yiidbActiveRecord;class User extends ActiveRecord 场景特性主要在验证 和 属性块赋值 中使用。 你也可以用于其他目的,例如可基于不同的场景定义不同的 属性标签。 验证规则当模型接收到终端用户输入的数据,数据应当满足某种规则(称为 验证规则,也称为 业务规则)。 例如假定ContactForm模型,你可能想确保所有属性不为空且 email 属性包含一个有效的邮箱地址, 如果某个属性的值不满足对应的业务规则,相应的错误信息应显示,以帮助用户修正错误。 可调用 yiibaseModel::validate() 来验证接收到的数据, 该方法使用yiibaseModel::rules()申明的验证规则来验证每个相关属性, 如果没有找到错误,会返回 true,否则它会将错误保存在 yiibaseModel::errors 属性中并返回false,例如: // 用户输入数据赋值到模型属性$model->attributes = Yii::$app->request->post('ContactForm'); if ($model->validate()) { 通过覆盖 yiibaseModel::rules() 方法指定模型属性应该满足的规则来申明模型相关验证规则。 下述例子显示ContactForm模型申明的验证规则: 一条规则可用来验证一个或多个属性,一个属性可对应一条或多条规则。 更多关于如何申明验证规则的详情请参考 验证输入 一节. 有时你想一条规则只在某个 场景 下应用,为此你可以指定规则的 on 属性,如下所示: 'register'],// 在 "login" 场景下 username 和 password 必须有值 [['username','on' => 'login'],]; }如果没有指定 on 属性,规则会在所有场景下应用, 在当前yiibaseModel::scenario 下应用的规则称之为 active rule活动规则。 一个属性只会属于scenarios()中定义的活动属性且在rules()申明对应一条或多条活动规则的情况下被验证。 块赋值块赋值只用一行代码将用户所有输入填充到一个模型,非常方便, 它直接将输入数据对应填充到 yiibaseModel::attributes 属性。 以下两段代码效果是相同的,都是将终端用户输入的表单数据赋值到 ContactForm 模型的属性, 明显地前一段块赋值的代码比后一段代码简洁且不易出错。 attributes = Yii::$app->request->post('ContactForm'); $model = new appmodelsContactForm; $data = Yii::$app->request->post('ContactForm',[]); $model->name = isset($data['name']) ? $data['name'] : null; $model->email = isset($data['email']) ? $data['email'] : null; $model->subject = isset($data['subject']) ? $data['subject'] : null; $model->body = isset($data['body']) ? $data['body'] : null;安全属性块赋值只应用在模型当前yiibaseModel::scenario场景yiibaseModel::scenarios()方法 列出的称之为 安全属性 的属性上,例如,如果User模型申明以下场景, 当当前场景为login时候,只有username and password 可被块赋值,其他属性不会被赋值。 ['username',]; }补充: 块赋值只应用在安全属性上,因为你想控制哪些属性会被终端用户输入数据所修改, 例如,如果 User 模型有一个permission属性对应用户的权限, 你可能只想让这个属性在后台界面被管理员修改。 由于默认yiibaseModel::scenarios()的实现会返回yiibaseModel::rules()所有属性和数据, 如果不覆盖这个方法,表示所有只要出现在活动验证规则中的属性都是安全的。 为此,提供一个特别的别名为 safe 的验证器来申明哪些属性是安全的不需要被验证, 如下示例的规则申明 title 和 description都为安全属性。 非安全属性(编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
