- Yii 教程
- Yii - 首页
- Yii - 概述
- Yii - 安装
- Yii - 创建页面
- Yii - 应用结构
- Yii - 入口脚本
- Yii - 控制器
- Yii - 使用控制器
- Yii - 使用动作
- Yii - 模型
- Yii - 小部件
- Yii - 模块
- Yii - 视图
- Yii - 布局
- Yii - 资源
- Yii - 资源转换
- Yii - 扩展
- Yii - 创建扩展
- Yii - HTTP 请求
- Yii - 响应
- Yii - URL 格式
- Yii - URL 路由
- Yii - URL 规则
- Yii - HTML 表单
- Yii - 验证
- Yii - 特设验证
- Yii - AJAX 验证
- Yii - 会话
- Yii - 使用闪存数据
- Yii - Cookie
- Yii - 使用 Cookie
- Yii - 文件上传
- Yii - 格式化
- Yii - 分页
- Yii - 排序
- Yii - 属性
- Yii - 数据提供者
- Yii - 数据小部件
- Yii - ListView 小部件
- Yii - GridView 小部件
- Yii - 事件
- Yii - 创建事件
- Yii - 行为
- Yii - 创建行为
- Yii - 配置
- Yii - 依赖注入
- Yii - 数据库访问
- Yii - 数据访问对象
- Yii - 查询构建器
- Yii - Active Record
- Yii - 数据库迁移
- Yii - 主题
- Yii - RESTful API
- Yii - RESTful API 实践
- Yii - 字段
- Yii - 测试
- Yii - 缓存
- Yii - 片段缓存
- Yii - 别名
- Yii - 日志记录
- Yii - 错误处理
- Yii - 身份验证
- Yii - 授权
- Yii - 本地化
- Yii - Gii
- Gii – 创建模型
- Gii – 生成控制器
- Gii – 生成模块
- Yii 有用资源
- Yii - 快速指南
- Yii - 有用资源
- Yii - 讨论
Yii - 模型
模型是表示业务逻辑和规则的对象。要创建模型,您应该扩展yii\base\Model类或其子类。
属性
属性表示业务数据。它们可以像数组元素或对象属性一样访问。每个属性都是模型的公共可访问属性。要指定模型拥有的属性,您应该重写yii\base\Model::attributes()方法。
让我们看一下基本应用程序模板的ContactForm模型。
<?php namespace app\models; use Yii; use yii\base\Model; /** * ContactForm is the model behind the contact form. */ class ContactForm extends Model { public $name; public $email; public $subject; public $body; public $verifyCode; /** * @return array the validation rules. */ public function rules() { return [ // name, email, subject and body are required [['name', 'email', 'subject', 'body'], 'required'], // email has to be a valid email address ['email', 'email'], // verifyCode needs to be entered correctly ['verifyCode', 'captcha'], ]; } /** * @return array customized attribute labels */ public function attributeLabels() { return [ 'verifyCode' => 'Verification Code', ]; } /** * Sends an email to the specified email address using the information collected by this model. * @param string $email the target email address * @return boolean whether the model passes validation */ public function contact($email) { if ($this->validate()) { Yii::$app->mailer->compose() ->setTo($email) ->setFrom([$this->email => $this->name]) ->setSubject($this->subject) ->setTextBody($this->body) ->send(); return true; } return false; } } ?>
步骤 1 - 在SiteController中创建一个名为actionShowContactModel的函数,代码如下。
public function actionShowContactModel() { $mContactForm = new \app\models\ContactForm(); $mContactForm->name = "contactForm"; $mContactForm->email = "[email protected]"; $mContactForm->subject = "subject"; $mContactForm->body = "body"; var_dump($mContactForm); }
在上面的代码中,我们定义了ContactForm模型,设置了属性,并在屏幕上显示了模型。
步骤 2 - 现在,如果您在 Web 浏览器的地址栏中输入https://127.0.0.1:8080/index.php?r=site/show-contact-model,您将看到以下内容。
如果您的模型扩展自yii\base\Model,则其所有成员变量(公共和非静态)都是属性。ContactForm模型中有五个属性 - name、email、subject、body、verifyCode,您可以轻松添加新的属性。
属性标签
您通常需要显示与属性关联的标签。默认情况下,属性标签由yii\base\Model::generateAttributeLabel()方法自动生成。要手动声明属性标签,您可以重写yii\base\Model::attributeLabels()方法。
步骤 1 - 如果您打开https://127.0.0.1:8080/index.php?r=site/contact,您将看到以下页面。
请注意,属性标签与其名称相同。
步骤 2 - 现在,以以下方式修改ContactForm模型中的attributeLabels函数。
public function attributeLabels() { return [ 'name' => 'name overridden', 'email' => 'email overridden', 'subject' => 'subject overridden', 'body' => 'body overridden', 'verifyCode' => 'verifyCode overridden', ]; }
步骤 3 - 如果您再次打开https://127.0.0.1:8080/index.php?r=site/contact,您会注意到标签已更改,如下所示。
场景
您可以在不同的场景中使用模型。例如,当访客想要发送联系表单时,我们需要所有模型属性。当用户想要执行相同的操作时,他已经登录,因此我们不需要他的姓名,因为我们可以轻松地从数据库中获取。
要声明场景,我们应该重写scenarios()函数。它返回一个数组,其键是场景名称,值是活动属性。活动属性是需要验证的属性。它们也可以批量赋值。
步骤 1 - 以以下方式修改ContactForm模型。
<?php namespace app\models; use Yii; use yii\base\Model; /** * ContactForm is the model behind the contact form. */ class ContactForm extends Model { public $name; public $email; public $subject; public $body; public $verifyCode; const SCENARIO_EMAIL_FROM_GUEST = 'EMAIL_FROM_GUEST'; const SCENARIO_EMAIL_FROM_USER = 'EMAIL_FROM_USER'; public function scenarios() { return [ self::SCENARIO_EMAIL_FROM_GUEST => ['name', 'email', 'subject', 'body', 'verifyCode'], self::SCENARIO_EMAIL_FROM_USER => ['email' ,'subject', 'body', 'verifyCode'], ]; } /** * @return array the validation rules. */ public function rules() { return [ // name, email, subject and body are required [['name', 'email', 'subject', 'body'], 'required'], // email has to be a valid email address ['email', 'email'], // verifyCode needs to be entered correctly ['verifyCode', 'captcha'], ]; } /** * @return array customized attribute labels */ public function attributeLabels() { return [ 'name' => 'name overridden', 'email' => 'email overridden', 'subject' => 'subject overridden', 'body' => 'body overridden', 'verifyCode' => 'verifyCode overridden', ]; } /** * Sends an email to the specified email address using the information collected by this model. * @param string $email the target email address * @return boolean whether the model passes validation */ public function contact($email) { if ($this -> validate()) { Yii::$app->mailer->compose() ->setTo($email) ->setFrom([$this->email => $this->name]) ->setSubject($this->subject) ->setTextBody($this->body) ->send(); return true; } return false; } } ?>
我们添加了两个场景。一个是针对访客的,另一个是针对已认证用户的。当用户已认证时,我们不需要他的姓名。
步骤 2 - 现在,修改SiteController的actionContact函数。
public function actionContact() { $model = new ContactForm(); $model->scenario = ContactForm::SCENARIO_EMAIL_FROM_GUEST; if ($model->load(Yii::$app->request->post()) && $model-> contact(Yii::$app->params ['adminEmail'])) { Yii::$app->session->setFlash('contactFormSubmitted'); return $this->refresh(); } return $this->render('contact', [ 'model' => $model, ]); }
步骤 3 - 在 Web 浏览器中输入https://127.0.0.1:8080/index.php?r=site/contact。您会注意到,目前所有模型属性都是必需的。
步骤 4 - 如果您按照以下代码中给出的方式更改actionContact中模型的场景,您会发现 name 属性不再是必需的。
$model->scenario = ContactForm::SCENARIO_EMAIL_FROM_USER;
批量赋值
批量赋值是一种通过一行代码从多个输入属性创建模型的便捷方法。
代码行是:
$mContactForm = new \app\models\ContactForm; $mContactForm->attributes = \Yii::$app->request->post('ContactForm');
上面给出的代码行等效于:
$mContactForm = new \app\models\ContactForm; $postData = \Yii::$app->request->post('ContactForm', []); $mContactForm->name = isset($postData['name']) ? $postData['name'] : null; $mContactForm->email = isset($postData['email']) ? $postData['email'] : null; $mContactForm->subject = isset($postData['subject']) ? $postData['subject'] : null; $mContactForm->body = isset($postData['body']) ? $postData['body'] : null;
前者更简洁。请注意,批量赋值仅适用于安全属性。它们只是scenario()函数中列出的当前场景属性。
数据导出
模型通常需要导出为不同的格式。要将模型转换为数组,请修改SiteController的actionShowContactModel函数:
public function actionShowContactModel() { $mContactForm = new \app\models\ContactForm(); $mContactForm->name = "contactForm"; $mContactForm->email = "[email protected]"; $mContactForm->subject = "subject"; $mContactForm->body = "body"; var_dump($mContactForm->attributes); }
在地址栏中输入https://127.0.0.1:8080/index.php?r=site/show-contact-model,您将看到以下内容:
要将模型转换为JSON格式,请以以下方式修改actionShowContactModel函数:
public function actionShowContactModel() { $mContactForm = new \app\models\ContactForm(); $mContactForm->name = "contactForm"; $mContactForm->email = "[email protected]"; $mContactForm->subject = "subject"; $mContactForm->body = "body"; return \yii\helpers\Json::encode($mContactForm); }
浏览器输出:
{ "name":"contactForm", "email":"[email protected]", "subject":"subject", "body":"body ", "verifyCode":null }
要点
在设计良好的应用程序中,模型通常比控制器快得多。模型应该:
- 包含业务逻辑。
- 包含验证规则。
- 包含属性。
- 不嵌入 HTML。
- 不直接访问请求。
- 不要有太多场景。