屬性代表業務資料。它們可以像陣列元素或物件的屬性那樣來存取。一個模型的每個屬性都是公開存取的屬性。要指定模型擁有什麼屬性,應該重寫yii\base\Model::attributes() 方法。
<?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; } } ?>
public function actionShowContactModel() { $mContactForm = new \app\models\ContactForm(); $mContactForm->name = "contactForm"; $mContactForm->email = "[email protected]"; $mContactForm->subject = "標題"; $mContactForm->body = "內容主體"; var_dump($mContactForm); }
如模型是從 yii\base\Model 擴充套件,那麼它的所有成員變數應該為公共且是非靜態的屬性。在 ContactForm 模型五個屬性 - name, email, subject, body, verifyCode,也可以再新增一些新的。
在應用中我們經常需要使用屬性相關聯來顯示標籤。預設情況下,屬性標籤由 yii\base\Model::generateAttributeLabel() 方法自動生成。要手動宣告屬性標籤,可以覆蓋yii\base\Model::attributeLabels() 方法。
public function attributeLabels() { return [ 'name' => '名字', 'email' => '郵箱地址', 'subject' => '標題', 'body' => '內容', 'verifyCode' => '驗證碼', ]; }
可以使用模型在不同的場景。 例如,當一個存取使用者要傳送一份聯絡表單,我們需要所有的模型屬性。 當使用者已經登入,我們並不需要他的名字,因為我們可以很容易地從資料庫把它讀取出來。
要宣告場景,應該覆蓋 scenarios() 函式。它返回一個陣列,其鍵是場景名稱而其值是 Active 屬性。Active屬性是用來來驗證的。它們也可以被大量分配。
<?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' => '名字', 'email' => '電子郵箱', 'subject' => '標題', 'body' => '內容', 'verifyCode' => '驗證碼', ]; } /** * 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; } } ?>
我們增加了兩個場景。一個用於存取遊客使用者,另一個用於身份驗證的使用者。當使用者通過驗證後,再不需要他填入名字。
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步 - 在瀏覽器存取URL => http://localhost:8080/index.php?r=site/contact 。你應該已經注意到,當前所有模型的屬性都是必須的。
$model->scenario = ContactForm::SCENARIO_EMAIL_FROM_USER;
$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;
前者乾淨多了。注意,大量分配僅適用於安全屬性。它們只是在 scenario() 函式中列出當前場景屬性。
模型往往需要以不同的格式匯出。要轉模型轉換為陣列,則修改 SiteController 的 actionShowContactModel() 函式-
public function actionShowContactModel() { $mContactForm = new \app\models\ContactForm(); $mContactForm->name = "使用者名稱"; $mContactForm->email = "[email protected]"; $mContactForm->subject = "標題"; $mContactForm->body = "內容"; var_dump($mContactForm->attributes); }
public function actionShowContactModel() { $mContactForm = new \app\models\ContactForm(); $mContactForm->name = "username"; $mContactForm->email = "[email protected]"; $mContactForm->subject = "subject"; $mContactForm->body = "body-content"; return \yii\helpers\Json::encode($mContactForm); }