在TP中,咱們只要在模型類中定義一個 php
protected $_map = array( 'name' =>'username', // 把表單中name映射到數據表的username字段 'mail' =>'email', // 把表單中的mail映射到數據表的email字段 );
在模型收集表單數據時會自動將值同時映射到username字段上。 前端
好處是避免數據庫字段直接暴露。 web
但很遺憾,我在學習Yii過程當中沒有找到相似的機制,而Yii的類庫不少,我又不敢貿然本身擴展,總以爲在某個角落裏有某個類可能已經提供瞭解決方案,怕本身作重複無心義之舉。 數據庫
通過一系列的思想鬥爭,樓主仍是決定本身動手啦。。 post
方法很簡單,請先看代碼: 學習
<?php class CustomModel extends CActiveRecord { //定義所須要收集的屬性 public $username; public $email; public $passwd; public $password; public $password1; public static function model($className=__CLASS__) { return parent::model($className); } public function tableName() { return '{{custom}}'; } public function rules(){ return array( array("username,password,email,password1","safe") ); } //字段映射配置 protected $_alias_ = array( "passwd" => "password" ); //經過引用傳遞處理映射 protected function afterConstruct(){ parent::afterConstruct(); //字段映射處理 if(!empty($this->_alias_)){ foreach($this->_alias_ as $a => $b){ if(property_exists($this,$a) && property_exists($this,$b)){ $this->$a = &$this->$b; } } } } }
<?php defined("APP_NAME") or exit;?> <form action="" method="post"> <table> <tr> <th>用戶名:</th> <td><input type="text" name="username" placeholder="請設置您的帳號名" value=""/></td> </tr> <tr> <th>郵箱:</th> <td><input type="email" name="email" placeholder="example@website" value=""/></td> </tr> <tr> <th>密碼:</th> <td><input type="password" name="password" value=""/></td> </tr> <tr> <th>重複密碼:</th> <td><input type="password" name="password1" value=""/></td> </tr> <tr> <td colspan="2"><input type="submit" value="提交"/></td> </tr> </table> </form>
因此我在模型類中定義了1個方法: this
afterConstruct()一個屬性
protected $_alias_咱們在$_alias_這個屬性裏面定義映射,好比我定義了 "passwd"=>"password"的映射。
afterConstruct()這個方法是在你實例化模型類以後執行的,能夠當作在 $model = new CustomModel()的時候觸發,這裏面主要作了一個工做,就是檢測$_alias_有沒有定義映射,若是有的話,咱們使用php的引用傳遞特性來使兩個字段指向同一個值。 spa
最後,爲了能夠全局使用,建議在components/目錄下創建一個 CommonModel類,將afterConstruct()方法放在這個類裏,其餘模型繼承這個類就能夠了,這樣只要在各自的模型中定義_alias_屬性便可。 code
/////////基於事件的處理方法 component
<?php class CommonAR extends CActiveRecord{ function init(){ $this->onAfterConstruct = array($this,"autoMap"); } //字段映射配置 protected $_alias_ = array( ); function autoMap($event){ //字段映射處理 if(!empty($this->_alias_)){ foreach($this->_alias_ as $a => $b){ if(property_exists($this,$a) && property_exists($this,$b)){ $this->$a = &$this->$b; } } } } }
$this->onAfterConstruct = array($this,"autoMap");對應的事件方法就是類裏面的autoMap()
而後建立具體模型的時候繼承CommonAR類,定義$_alias_便可。