本文概述
模型是MVC结构的一部分。它们代表了应用程序的规则和逻辑。意味着它们保存数据并定义数据的验证规则。
模型类由yii \ base \ Model或其子类扩展。
主要使用模型实现以下功能。
- 属性声明
- 属性标签
- 大量属性分配
- 基于场景的验证
- 无法嵌入HTML
- 无法直接访问
属性
属性主要代表业务数据。每个属性都是模型的可公开访问的属性。可以像访问数组元素或常规对象属性一样访问它们。就像模型的公共属性一样。
方法,
yii\base\Model::attributes()
指定模型类具有的属性。
模型类还是ActiveRecord类(它是具有附加功能的高级模型)的基类。
作为普通对象属性的属性:
$model = new \app\models\ContactForm;
// "name" is an attribute of ContactForm
$model->name = 'example';
echo $model->name;
Attribute as array elements:
$model = new \app\models\ContactForm;
// accessing attributes like array elements
$model['name'] = 'example';
echo $model['name'];
// Model is traversable using foreach.
foreach ($model as $name => $value) {
echo "$name: $value\n";
}
在Yii的早期版本中, 方案和验证使用相同的功能处理。但是在Yii2中, 它们分为不同的功能, 即; rules()和visions()。
在这里, rules()指定数据的验证, 而visions()指定可以安全地分配给模型的属性。
属性标签
属性标签是与属性一起显示的值, 以从用户那里获取输入。
例如, 在下面的代码中, ID, 名称, 名称, 联系方式和电子邮件表示属性标签。所有这些都在函数attributeLabels()下定义。
public function attributeLabels()
{
return [
'id' => 'ID', 'name' => 'Name', 'designation' => 'Designation', 'contact' => 'Contact', 'email' => 'Email', ];
}
查看上面的快照, 标题数据表示属性标签。
场景
模型可以用于不同的场景。例如, 模型可以用于收集登录用户输入, 而模型也可以用于收集新用户的输入以进行注册。因此, 在不同的情况下, 模型可以使用不同的规则和逻辑。
例子
这是ContactForm.php代码,
<?php
namespace frontend\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 => ['name', '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', 'email' => 'Email', 'subject' => 'Subject', 'body' => 'Body', '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;
}
}
?>
在SiteController.php文件中创建一个动作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, ]);
}
现在, 我们将在浏览器中运行该程序,
现在, 将SiteController.php中的actionn更改为actionContact,
$model->scenario = ContactForm::SCENARIO_EMAIL_FROM_USER;
现在, 在浏览器中运行程序时, “主题”和”正文”字段将不再是必填字段。
验证规则
这些是为用户要填写的字段设置的规则。例如, 必填规则将确保相应的字段不为空。电子邮件属性将确保输入的电子邮件是有效的电子邮件。如果值不符合规则, 则屏幕上将显示一条错误消息。
要声明所有方案中所有字段的验证规则, 请使用以下代码。
public function rules()
{
return [
// the name, email, subject and body attributes are required
[['name', 'email', 'subject', 'body'], 'required'], // the email attribute should be a valid email address
['email', 'email'], ];
}
To declare different validation rules for different scenarios, use the following code.
public function rules()
{
return [
// username, email and password are all required in "register" scenario
[['username', 'email', 'password', 'd_o_b'], 'required', 'on' => self::SCENARIO_REGISTER], // username and password are required in "login" scenario
[['username', 'password'], 'required', 'on' => self::SCENARIO_LOGIN], ];
}
on属性实现了将规则应用于特定方案的功能。如果你不使用on属性, 则默认情况下, 规则将应用于所有字段。
大规模分配
在大规模分配中, 使用单行代码用用户输入填充模型。大规模分配仅适用于安全属性。
查看以下两种类型的代码, 它们均将最终用户提交的表单数据分配给ContactForm模型的属性。
第一个是
$model = new \app\models\ContactForm;
$model->attributes = \Yii::$app->request->post('ContactForm');
Second one is, $model = new \app\models\ContactForm;
$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;
第一个使用大规模分配的方法更容易, 更简洁并且更不易出错。