屬性
屬性代表業務數據。它們可以像數組元素或對象的屬性那樣來訪問。一個模型的每個屬性都是公開訪問的屬性。要指定模型擁有什麼屬性,應該重寫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 = "user@gmail.com";
$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 = "user@gmail.com";
$mContactForm->subject = "標題";
$mContactForm->body = "內容";
var_dump($mContactForm->attributes);
}
public function actionShowContactModel() {
$mContactForm = new \app\models\ContactForm();
$mContactForm->name = "username";
$mContactForm->email = "user@gmail.com";
$mContactForm->subject = "subject";
$mContactForm->body = "body-content";
return \yii\helpers\Json::encode($mContactForm);
}

要點
- 包含業務邏輯
- 包含驗證規則
- 包含屬性
- 不嵌入HTML
- 不能直接訪問請求
-
不要有太多的場景




