Модели — это объекты, представляющие бизнес-логику и правила. Чтобы создать модель, вы должны расширить класс 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 = "[email protected]"; $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 = "[email protected]"; $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 = "[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 }
Важные моменты
Модели обычно намного быстрее, чем контроллеры в хорошо разработанном приложении. Модели должны —