Yii - Modelli

I modelli sono oggetti che rappresentano la logica e le regole aziendali. Per creare un modello, dovresti estendere il fileyii\base\Model classe o delle sue sottoclassi.

Attributi

Gli attributi rappresentano i dati aziendali. È possibile accedervi come elementi dell'array o proprietà degli oggetti. Ogni attributo è una proprietà accessibile pubblicamente di un modello. Per specificare quali attributi possiede un modello, è necessario sostituire il fileyii\base\Model::attributes() metodo.

Diamo uno sguardo al file ContactForm modello del modello di applicazione di base.

<?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 - Crea una funzione chiamata actionShowContactModel nel SiteController con il seguente codice.

public function actionShowContactModel() { 
   $mContactForm = new \app\models\ContactForm(); $mContactForm->name = "contactForm"; 
   $mContactForm->email = "[email protected]"; $mContactForm->subject = "subject"; 
   $mContactForm->body = "body"; var_dump($mContactForm); 
}

Nel codice sopra, definiamo il file ContactForm modello, impostare attributi e visualizzare il modello sullo schermo.

Step 2 - Ora, se digiti http://localhost:8080/index.php?r=site/show-contact-model nella barra degli indirizzi del browser web, vedrai quanto segue.

Se il tuo modello si estende da yii\base\Model, quindi tutte le sue variabili membro (pubbliche e non statiche) sono attributi. Ci sono cinque attributi inContactForm modello: nome, email, oggetto, corpo, verifyCode e puoi facilmente aggiungerne di nuovi.

Etichette degli attributi

Spesso è necessario visualizzare le etichette associate agli attributi. Per impostazione predefinita, le etichette degli attributi vengono generate automaticamente dayii\base\Model::generateAttributeLabel()metodo. Per dichiarare manualmente le etichette degli attributi, puoi sovrascrivere il fileyii\base\Model::attributeLabels() metodo.

Step 1 - Se apri http://localhost:8080/index.php?r=site/contact, vedrai la pagina seguente.

Notare che le etichette degli attributi sono le stesse dei loro nomi.

Step 2 - Ora, modifica il file attributeLabels funzione in ContactForm modello nel modo seguente.

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

Step 3 - Se apri http://localhost:8080/index.php?r=site/contact di nuovo, noterai che le etichette sono cambiate come mostrato nell'immagine seguente.

Scenari

È possibile utilizzare un modello in diversi scenari. Ad esempio, quando un ospite vuole inviare un modulo di contatto, abbiamo bisogno di tutti gli attributi del modello. Quando un utente vuole fare la stessa cosa, è già loggato, quindi non abbiamo bisogno del suo nome, in quanto possiamo prenderlo facilmente dal DB.

Per dichiarare scenari, dovremmo sovrascrivere il scenarios()funzione. Restituisce un array le cui chiavi sono i nomi e i valori dello scenarioactive attributes. Gli attributi attivi sono quelli da convalidare. Possono anche esseremassively assigned.

Step 1 - Modifica il file ContactForm modello nel modo seguente.

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

Abbiamo aggiunto due scenari. Uno per l'ospite e un altro per l'utente autenticato. Quando l'utente è autenticato, non abbiamo bisogno del suo nome.

Step 2 - Ora, modifica il file actionContact funzione del 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 - Tipo http://localhost:8080/index.php?r=site/contactnel browser web. Noterai che attualmente tutti gli attributi del modello sono obbligatori.

Step 4 - Se cambi lo scenario del modello nel file actionContact, come indicato nel codice seguente, scoprirai che l'attributo name non è più richiesto.

$model->scenario = ContactForm::SCENARIO_EMAIL_FROM_USER;

Assegnazione massiccia

L'assegnazione massiva è un modo conveniente per creare un modello da più attributi di input tramite una singola riga di codice.

Le righe di codice sono:

$mContactForm = new \app\models\ContactForm; 
$mContactForm->attributes = \Yii::$app->request->post('ContactForm');

Le righe di codice sopra riportate sono equivalenti a -

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

Il primo è molto più pulito. Notare chemassive assignment si applica solo a safe attributes. Sono solo gli attributi dello scenario corrente elencati nel filescenario() funzione.

Esportazione dei dati

I modelli spesso devono essere esportati in diversi formati. Per convertire il modello in un array, modificare il fileactionShowContactModel funzione del 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);
}

genere http://localhost:8080/index.php?r=site/show-contact-model nella barra degli indirizzi e vedrai quanto segue:

Per convertire il modello in JSON formato, modificare il file actionShowContactModel funzionare nel modo seguente:

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
}

Punti importanti

I modelli sono generalmente molto più veloci dei controller in un'applicazione ben progettata. I modelli dovrebbero:

  • Contenere la logica aziendale.
  • Contengono regole di convalida.
  • Contenere attributi.
  • Non incorporare HTML.
  • Non accedere direttamente alle richieste.
  • Non avere troppi scenari.