models是展示業務數據、規則和邏輯的對象。
你可以通過擴展yii/base/Model或者其子類來創建model類, 這個基類支持下面的特性:
Attributes
Attribute labels
Massive assignment
Validation rules
Data Exporting
Model Class還是某些更復雜的模型的基類,比如Active Record
原創文章, 轉載請注明 http://m.survivalescaperooms.com/ganiks/
3.6.1 Attributes訪問屬性并沒有強制說你一定要讓你的模型類基于
yii/base/Model,但是因為有很多的Yii的組件都是支持yii/base/Model的, 建議你還是基于它來構建你的模型。
yii/base/Model::attributes()制定了這個模型類含有哪些屬性, 訪問其屬性如下:
$model = new /app/models/ContactForm;$model->name = 'example';echo $model->name;也可以如下訪問屬性:
$model = new /app/models/ContactForm;$model['name'] = 'example';echo $model['name'];foreach($model as $name=>$value){ echo "$name:$value/n";}這要多謝 yii/base/Model對Arrayaccess和ArrayIterator的支持。http://php.net/manual/en/class.arrayaccess.phphttp://php.net/manual/en/class.arrayiterator.php
默認的, 如果你的 model直接擴展自yii/base/Model, 那么它所有的 non-static public 成員都是屬性。例如,下面這個就有4個屬性。
namespace app/models;use yii/base/Model;class ContactForm extends Model{ public $name; public $email; public $subject; public $body;}你也可以通過定義yii/base/Model::attributes()方法來定義屬性, 但是通常不這樣做,即使在ActiveRecord中,也常常是用tableName()來直接返回一個表名。
public static function tableName() { return '{{%user}}'; }屬性標簽$model = new /app/models/ContactForm;echo $model->getAttributeLabel('name');默認的, 這些labes是由方法yii/base/Model::generateAttributeLabel()自動生成, 經過轉換 ,firstName=>First Name
你也可以自定義:
public function attributeLabels() { return [ 'name' => 'Your name', 'email' => 'Your email address', 'subject' => /Yii::t('app', 'Subject'), ]; }3.6.2 Scenarios場景是個很有用的東西,能夠讓一個model在不同的情況下靈活使用。
舉例來說, 一個User模型可能用于采集用戶登錄的輸入,也可以用于注冊。在不同的情況下, 一個模型可能使用不同的業務和邏輯。比如,email屬性可能在用戶注冊時候才是必填的。
模型使用屬性yii/base/Model::scenario來記載目前所處的場景。默認的, 用的是一個default場景。
下面是兩種設置場景的方式:
$model = new User;$model->scenario = 'login';$model = new User(['scenario' => 'login']);默認的, 一個模型支持的場景是由其validataion rules中聲明的。但是,你也可以通過重寫下面的方法來自定義這個行為:
class User extends ActiveRecord{ public function scenarios() { return [ 'login' => ['username', 'passWord'], 'register' => ['username', 'email', 'password'] ]; }}多場景的模型多用于
ActiveRecord類模型。
scenarios()方法返回的是一個數組,鍵是場景名字,值則是相應的active attributes。
默認的像上面這樣的scenarios()返回的是在yii/base/Model::rules()中聲明的驗證規則中的所有的場景;而如果你要引入新的場景,則應該這樣做:
class User extends ActiveRecord{ public function scenarios() { $scenarios = parent::scenarios(); $scenarios['login'] = ['username', 'password']; ... return $scenarios; }}場景這個特性,主要用于“驗證”和“批零賦值”,也可以用于“指定labels”
3.6.3 Validation Rules調用validate
yii/base/Model::validate()if($model->validate()){ ...}聲明validation rules
yii/base/Model::rules()public function rules(){ return [ [['name', 'email', 'subject', 'body'], 'required', 'on' => 'register'], ['email', 'email'] ];}3.6.4 Massive Assignment一個屬性要想被validate(), 需要符合2個條件, 它在
scenarios()中被聲明為active attribute; 跟rules()中聲明的一個或者多個active rules相關聯另外, 如果屬性沒有自定on,則默認是適用于所有的場景
批量賦值,是一個方便的方法,可以用一行代碼就讓model跟用戶的輸入結合起來。它直接的把用戶的輸入賦給了yii/base/Model::attributes屬性。
下面是兩種方式,很明顯, 前者更簡潔:
$model = new ContactForm;$model->attributes = Yii::$app->request->post('ContactForm');$model = new ContactForm;$data = Yii::$app->request->post('ContactForm', []);$model->name = iseet($data['name']) ? $data['name'] : null ;... ...... ...Safe Attributes 安全屬性批量賦值,只作用于所謂的“安全屬性”, 也就是在yii/base/Model::scenarios()中列出的屬性;而其他的屬性則不會有所動。
安全屬性這個特性的好處在于,方便你控制那些屬性可以被終端用戶操作。
由于默認的yii/base/Model::scenarios()會返回yii/base/Model::rules()中所有的場景和屬性,如果你重寫這個方法,意味著只要出現在rules()中的屬性,就都是安全屬性。那如果我想要的安全屬性并不需要定義什么驗證規則怎么辦呢?基于這個原因,yii提供了safe來讓你單獨聲明安全屬性的規則
public function rules(){ return [ [['title', 'description'], 'safe'], ];}Unsafe Attributes 非安全屬性如上所述, yii/base/Model::scenarios()有兩個目的:
而有些極少數的情況下, 你可能想要validate一個屬性而并不想讓其safe
public function scenarios(){ return [ 'login' => ['username', 'password', '!secret'], ];}3.6.5 Data Exporting模型經常需要被導出為不同的格式。比如你可能想要將一系列的模型轉換到JSON或者Excel。
導出過程可以分為2步:
第二步很簡單,可以通過類似實現yii/web/JsonResponseFormatter;主要是第一步, 最簡單的方法是yii/base/Model::attributes
$post = /app/models/Post::findOne(100);$array = $post->attributes;還有一個更復雜的方法(用于RESTful API)中, 叫做 yii/base/Model::toArray(), 這個方法強大之處在于, 允許你決定最終的結果中包含哪些項目,叫做fileds,并且可以指定如何format
fieldspublic function fields(){ return [ 'id', 'email' => 'email_address', 'name' => function(){ return $this->first_name.' '. $this->last_name; } ];}public function fields(){ $fields = parent::fields(); unset($fields['auth_key'], $fields['password_hash']); return $fields;}新聞熱點
疑難解答