Модели — это объекты, представляющие бизнес-логику и правила. Чтобы создать модель, вы должны расширить класс yii \ base \ Model или его подклассы.
Атрибуты
Атрибуты представляют бизнес-данные. Они могут быть доступны как элементы массива или свойства объекта. Каждый атрибут является общедоступным свойством модели. Чтобы указать, какими атрибутами обладает модель, вы должны переопределить метод yii \ base \ Model :: attribute () .
Давайте посмотрим на модель 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 — Создайте функцию с именем actionShowContactModel в SiteController со следующим кодом.
public function actionShowContactModel() {
$mContactForm = new \app\models\ContactForm();
$mContactForm->name = "contactForm";
$mContactForm->email = "user@gmail.com";
$mContactForm->subject = "subject";
$mContactForm->body = "body";
var_dump($mContactForm);
}
В приведенном выше коде мы определяем модель ContactForm , устанавливаем атрибуты и отображаем модель на экране.
Шаг 2. Теперь, если вы введете http: // localhost: 8080 / index.php? R = site / show-contact-model в адресной строке веб-браузера, вы увидите следующее.

Если ваша модель выходит из yii \ base \ Model , то все ее переменные-члены (публичные и нестатические) являются атрибутами. В модели ContactForm есть пять атрибутов — имя, адрес электронной почты, тема, тело, verifyCode, и вы можете легко добавлять новые.
Метки атрибутов
Вам часто нужно отображать метки, связанные с атрибутами. По умолчанию метки атрибутов автоматически генерируются методом yii \ base \ Model :: generateAttributeLabel () . Чтобы вручную объявить метки атрибутов, вы можете переопределить метод yii \ base \ Model :: attributeLabels () .
Шаг 1 — Если вы откроете http: // localhost: 8080 / index.php? R = site / contact, вы увидите следующую страницу.

Обратите внимание, что метки атрибутов совпадают с их именами.
Шаг 2 — Теперь измените функцию attributeLabels в модели ContactForm следующим образом.
public function attributeLabels() {
return [
'name' => 'name overridden',
'email' => 'email overridden',
'subject' => 'subject overridden',
'body' => 'body overridden',
'verifyCode' => 'verifyCode overridden',
];
}
Шаг 3. Если вы снова откроете http: // localhost: 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 — Теперь измените функцию actionContact SiteController .
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 — Введите http: // localhost: 8080 / index.php? R = site / contact в веб-браузере. Вы заметите, что в настоящее время требуются все атрибуты модели.

Шаг 4. Если вы измените сценарий модели в actionContact , как указано в следующем коде, вы обнаружите, что атрибут name больше не требуется.
$model->scenario = ContactForm::SCENARIO_EMAIL_FROM_USER;

Massive Assignment
Массивное присваивание — это удобный способ создания модели из нескольких входных атрибутов с помощью одной строки кода.
Строки кода —
$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;
Первый намного чище. Обратите внимание, что массовое назначение применяется только к безопасным атрибутам . Это просто атрибуты текущего сценария, перечисленные в функции scene () .
Экспорт данных
Модели часто необходимо экспортировать в разных форматах. Чтобы преобразовать модель в массив, измените функцию actionShowContactModel в SiteController —
public function actionShowContactModel() {
$mContactForm = new \app\models\ContactForm();
$mContactForm->name = "contactForm";
$mContactForm->email = "user@gmail.com";
$mContactForm->subject = "subject";
$mContactForm->body = "body";
var_dump($mContactForm->attributes);
}
Введите http: // localhost: 8080 / index.php? R = site / show-contact-model в адресной строке, и вы увидите следующее —

Чтобы преобразовать модель в формат JSON , измените функцию actionShowContactModel следующим образом:
public function actionShowContactModel() {
$mContactForm = new \app\models\ContactForm();
$mContactForm->name = "contactForm";
$mContactForm->email = "user@gmail.com";
$mContactForm->subject = "subject";
$mContactForm->body = "body";
return \yii\helpers\Json::encode($mContactForm);
}
Вывод браузера —
{
"name":"contactForm",
"email":"user@gmail.com",
"subject":"subject",
"body":"body ",
"verifyCode":null
}