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;
      }
   }
?>

Step 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 モデル化し、属性を設定し、モデルを画面に表示します。

Step 2 −さて、入力すると http://localhost:8080/index.php?r=site/show-contact-model Webブラウザのアドレスバーに次のように表示されます。

モデルが yii\base\Modelの場合、そのすべてのメンバー変数(パブリックおよび非静的)は属性です。には5つの属性がありますContactForm モデル-名前、メールアドレス、件名、本文、 verifyCode 新しいものを簡単に追加できます。

属性ラベル

多くの場合、属性に関連付けられたラベルを表示する必要があります。デフォルトでは、属性ラベルはによって自動的に生成されますyii\base\Model::generateAttributeLabel()方法。属性ラベルを手動で宣言するには、yii\base\Model::attributeLabels() 方法。

Step 1 −開いた場合 http://localhost:8080/index.php?r=site/contact, 次のページが表示されます。

属性ラベルは名前と同じであることに注意してください。

Step 2 −ここで、 attributeLabels の機能 ContactForm 次のようにモデル化します。

public function attributeLabels() {
   return [
      'name' => 'name overridden',
      'email' => 'email overridden',
      'subject' => 'subject overridden',
      'body' => 'body overridden',
      'verifyCode' => 'verifyCode overridden',
   ];
}

Step 3 −開いた場合 http://localhost:8080/index.php?r=site/contact ここでも、次の画像に示すようにラベルが変更されていることがわかります。

シナリオ

さまざまなシナリオでモデルを使用できます。たとえば、ゲストが連絡フォームを送信する場合、すべてのモデル属性が必要です。ユーザーが同じことをしたいとき、彼はすでにログインしているので、DBから簡単に取得できるので、彼の名前は必要ありません。

シナリオを宣言するには、 scenarios()関数。キーがシナリオ名で値がである配列を返します。active attributes。アクティブな属性は検証するものです。彼らはまたすることができますmassively assigned

Step 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つのシナリオを追加しました。1つはゲスト用で、もう1つは認証済みユーザー用です。ユーザーが認証されるとき、私たちは彼の名前を必要としません。

Step 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,
   ]);
}

Step 3 −タイプ http://localhost:8080/index.php?r=site/contactWebブラウザで。現在、すべてのモデル属性が必要であることに気付くでしょう。

Step 4 −でモデルのシナリオを変更した場合 actionContact、次のコードに示されているように、name属性は不要になっていることがわかります。

$model->scenario = ContactForm::SCENARIO_EMAIL_FROM_USER;

大規模な割り当て

大規模な割り当ては、1行のコードを介して複数の入力属性からモデルを作成する便利な方法です。

コードの行は次のとおりです。

$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;

前者の方がはるかにクリーンです。そのことに注意してくださいmassive assignment にのみ適用されます safe attributes。これらは、にリストされている現在のシナリオ属性です。scenario() 関数。

データのエクスポート

多くの場合、モデルはさまざまな形式でエクスポートする必要があります。モデルを配列に変換するには、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);
}

Browser output

{
   "name":"contactForm",
   "email":"[email protected]",
   "subject":"subject",
   "body":"body ",
   "verifyCode":null
}

重要なポイント

モデルは通常、適切に設計されたアプリケーションのコントローラーよりもはるかに高速です。モデルは-

  • ビジネスロジックが含まれています。
  • 検証ルールが含まれています。
  • 属性が含まれています。
  • HTMLを埋め込みません。
  • リクエストに直接アクセスしません。
  • シナリオが多すぎない。