TP5 Model 功能總結

來源:互聯網
上載者:User

TP5提供了強大的Model功能,跟隨這篇文章來一探究竟。

簡介

  1. tp5的model只做業務層操作,不做具體的連結資料庫sql操作。

  2. think\db\Connection.php做連結資料庫操作

  3. think\db\Builder.php做建立sql操作

  4. think\db\Query.php做資料CURD操作

功能清單

  1. 資料自動完成

  2. 自動寫入時間戳記

  3. 時間欄位自動格式化輸出欄位

  4. 欄位驗證器

  5. 自動關聯寫入

  6. 唯讀欄位

  7. 隱藏欄位

  8. 事件回調

  9. 虛刪除

  10. 類型轉換

功能詳情

1. 資料自動完成

   //設定自動完成的欄位,支援索引值對數組和索引數組    //新增和更新時都會使用    //如:['name'=>'zhangsan','sex'=>'男']    // ['name','sex']    protected $auto = [];    //新增 自動完成列表    //只在新增資料的時候使用    protected $insert = [];    //更新 自動完成列表    //只在更新資料的時候使用    protected $update = [];    //用來標記當前操作被修改的欄位    //如 ['name','sex']    protected $change = [];    //依賴方法,model類會自動調用解析auto數組    //我們只需配置auto數組即可    protected function autoCompleteData($auto = []){}

在model中設定完auto欄位後在更新或新增的時候首先會判斷auto中設定的欄位是否存在於被更新的欄位($this->change)中

如果存在則不用auto裡設定的欄位和值

如果不存在則將auto裡設定的欄位和值添加到this−>data中並把該欄位新增到this->change中。

如果auto是索引數組,也就是只設定了欄位名,沒有設定子欄位值,這是就會根據欄位名去$this->data中查詢該欄位值,並添加的到要更新的屬性數組中去。

新增資料的方法是create, 修改資料的方法是update,批量新增和修改的方法是saveAll,這幾個方法的最終實現都是調用的save方法

saveAll方法批量新增和修改,並不是組合sql語句,而是開啟事務,然後調用save方法,一條一條添加和修改,最後提交事務。

在更新操作中,model會自動檢查data的所有欄位的值是否被更改,只會跟新被更改過得欄位的值。沒被更改的則被忽略。

insert、update的功能和auto的功能類似,只不過auto是不管是新增資料和是更新資料都會使用,而insert值針對新增,update只針對更新。如果設定了相同的屬性,insert和update的則會覆蓋auto中的欄位。

2. 自動寫入時間戳記

   //是否需要自動寫入時間戳記    //可以是字串類型和boolean類型    //字串類型代表要寫入的時間格式    //如: 'Y-m-d H:i:s'    //boolean類型就是true和false,代表是否開啟    //預設時間格式為int類型    protected $autoWriteTimestamp;    //預設自動寫入的欄位有    //建立時間和更新時間,他們對應的欄位名分別是    //create_time,和update_time    //也可以在model裡自己設定。    protected $createTime = 'create_time';    protected $updateTime = 'update_time';

配置方式

該配置TP5預設為false,需要手動開啟

在資料庫配置(database.php)中添加全域配置。

   'auto_timestamp' => true    //或者設定時間格式    // 'auto_timestamp' => 'datatime'

在單獨的模型類裡設定

   protected $autoWriteTimestamp = true;    //或者設定時間格式    // protected $autoWriteTimestamp = 'datatime';

知識的欄位類型 timestamp/datetime/int

如果自己的資料欄位不是預設值得話,可以在自己的model裡修改。

   //如:    protected $createTime = 'my_create_time_filed';        protected $updateTime = 'my_careate_time_field';

如果只需要createTime而不需要updateTIme,則可以在model中關閉updateTIme

   //如    protected $updateTime = false;123

在model中開啟和關閉只針對單獨的model起作用,想要全域起作用還是要在設定檔裡配置。

3. 時間欄位自動格式化輸出

   //輸出格式    protected $dateFormat;123

配置方式

該配置TP5模式輸出格式為 ‘Y-m-d H:i:s’

可以自己在資料庫設定檔(database.php)中配置。如

   'datetime_format' => 'Y/m/d H:i',12

也可以在model中設定

   protected $dateFormat = 'Y/m/d H:i';12

4. 欄位驗證器

   //欄位驗證規則    protected $validate = [];    //是否採用批量驗證    protected $batchValidate = false;    /**     * 設定欄位驗證     * @access public     * @param array|string|bool $rule  驗證規則 true表示自動讀取驗證器類     * @param array             $msg   提示資訊     * @param bool              $batch 批量驗證     * @return $this     */    public function validate($rule = ture,$msg=[],$bath=false){}    /**     * 自動驗證資料     * @access protected     * @param array $data  驗證資料     * @param mixed $rule  驗證規則     * @param bool  $batch 批量驗證     * @return bool     */    public function validateData($data,$rule=null,$batch=null){}

使用方式

在model中配置欄位驗證規則,在整個model中新增和更新操作都通用。

// 優點:只需要設定一次,即可通用
// 缺點:無法針對化設定
//比如:新增使用者和編輯使用者功能,
//新增是密碼為必填項,編輯時密碼就是選填項了
//所以就不能再model裡設定密碼的驗證規則了,
這個時候就只能在新增的action裡為密碼做驗證了。

protected $validate = [                'rule' => [                            'name' => 'require',                            //多個規則可以是用字串用|分隔           //也可以使用數組['require','number','min'=>10,'max'=>80]           //使用字串配置要被使用explode('|',$rule)轉化成數組,所以使用數組配置效率更高           'age' => 'require|number|min:10|max:80',                       'height' => 'between:100,200'        ],               'msg' => [                         'name' => 'name不可為空',                         'age.require' => 'age不能沒空',                         'age.number' => 'age必須是一個數字',                         'age.min' => 'age最小為10',                         'age.max' => 'age最大為80',                         'height' => 'height只能在100到200之間'        ]    ];

在具體操作時調用think\Validate類來實現

   //在類的頭部,因為Validate檔案。    use think\Validate;        $validate = new Validate([            'name' => 'require',           'age' => 'require|number|min:10|max:80'    ],[                  'name' => 'name不可為空',                  'age.require' => 'age不能沒空',                  'age.number' => 'age必須是一個數字',                  'age.min' => 'age最小為10',                  'age.max' => 'age最大為80',    ]);        //使用check檢查資料    if($validate->check($data)){            echo '資料格式符合要求';    }else{                //比如:name不可為空        echo $validate->getError();    }

對比

使用第一種方法在model裡設定驗證規則,雖然說結構看著比較合理,但是這種方法靈活性比較低,因為他是在save的時候去判斷的,如果save失敗,你不清楚是資料驗證失敗,還是說插入到資料失敗。所以對於做提示驗證很麻煩(因為資料驗證的提示我們是直接返回給使用者的,而資料庫操作的提示一般我們是不返回給使用者的,所以得到結果後還要做判斷,先對比較麻煩)。

使用第二種方法在action裡定義一個_validate的函數,專門用來做資料校正,這中方法比較靈活,而且他是在在儲存資料之前做的校正,所以返回結果分的比較清楚,對使用者的提示也比較清晰,代碼可讀性也比較好。

5. 自動關聯寫入

   // 關聯對象    protected $relation;    // 關聯自動寫入(關聯的屬性名稱)    protectd $relationWrite = [];

暫時沒有使用,後續再繼續不補充。

6. 唯讀欄位

   //用來保護那些不許要被更新的欄位。    //比如,建立時間    //設定後再更新資料時,會欄位過濾掉create_time欄位    //避免更新到資料庫。    protected $readonly = ['create_time'];

7. 隱藏欄位

    //設定要隱藏的欄位,    //該設定只在toArray(),和subToArray()方法中起作用    protected $hidden = [];    //相關方法    public function hidden($hidden=[],$override=false){    }

當使用toArray和subToArray獲得數組資料時,使用hidden欄位和hidden函數可以隱藏數組中的元素。如:

    //user表的屬性欄位(類比操作)    user_field = ['name','sex','age','height'];

在User模型中設定$hidden欄位

   protected $hidden = ['age','height'];    dump($User->toArray()); //只有name和sex欄位。    //也可以調用hidden方法隱藏欄位    //會有 name,age,height 三個欄位    dump($User->hidde(['sex'])->toArray());     //只有name欄位了    //第二個參數標識是否合并 $this->hidden     dump($user->hidden(['sex'],true)->toArray());

8. 事件回調

支援的回調事件

before_insert 新增前

after_insert 新增後

before_update 更新前

after_update 更新後

before_write 寫入前(新增和更新都會調用)

after_write 寫入後(新增和更新都會調用)

before_delete 刪除前

after_delete 刪除後

註冊的回調方法支援傳入一個參數,當前樣本模型對象,並且before_write,before_insert,before_update,before_delete返回false會結束執行。

使用方法

控制器裡使用

   //支援給一個位置註冊多個事件       User::event('before_insert',function($user){               if($user->status != 1){                       return false;               }       });        //這個也會生效,回到函數為beforeInsert      User::event('before_insert','beforeInsert');

模型裡使用

   //使用init方法統一註冊模型事件    class User extends Model{        protected static function init(){            User::event('before_insert',function($user){                if($user->status != 1){                                        return false;                }            }                        //註冊第二個事件            User::event('before_insert','beforeInsert');        }    }

原理

model類裡有一個protected static $event = [];屬性,註冊的時間都存放在這個屬性中。比如:

   $event = [                  //模型名稱        'user' => [                          //事件名稱            'before_insert' => ['callback_funciton','beforeInsert'],                        'after_insert' => ['callback_function','afterInsert'],                        'before_delete' => ['beforeDelete']        ]    ]

註冊事件時,把所有的事件都儲存在$event中了,然後在insert,update,delete等相應的位置調用即可。

9. 虛刪除

簡介

在實際項目中,對資料頻繁的使用刪除操作可能會導致效能問題,虛刪除的作用就是給資料加上刪除標記,而不是真正的刪除,同時也便於需要的時候恢複資料。

設定方式

使用虛刪除功能需要引用SoftDelete trait;如:

   namespace app\index\model;       use think\Model;       use think\model\SoftDelete;       class User extends Model{        // 使用SoftDelete        // trait 的使用方式        // 使用trait跟類的繼承相似        use SoftDelete;                //虛刪除標記的欄位名        protected $deleteTime = 'delete_time';    }

dateteTIme屬性用於標記資料表裡的虛刪除欄位,TP5裡的虛刪除使用的是int類型,預設值為null(這個很重要,因為查詢的時候是用delete_time is not null 來查詢的),用於記錄刪除時間。

可以用類型轉換指定虛刪除的欄位類型,建議資料表裡的所有時間欄位使用同一種資料類型。

使用方式

在model中設定好後,就可以直接使用了

   //虛刪除    User::destory(1);        //真刪除    User::destory(1,true);        //虛刪除    $user = User::get(1);        $user->delete();        //真刪除    $user->delete(true);

預設情況下,查詢出來的資料是不包括虛刪除的資料的,如果想要查詢包括虛刪除的資料,可以使用下面的方式。

    User::withTrashed()->find();   User::withTrashed()->select();

如果僅需要查詢虛刪除的資料,可以這樣:

    User::onlyTranshed()->find();   User::onlyTranshed()->select();

10. 類型轉換

TP5支援給資料表中的欄位設定類型,並會在讀取和寫入的時候自動轉換。如:

   class User extends Model{        protected $type = [                        'status' => 'integer',                        'score' => 'float',                        'login_timme' => 'datetime',                        'info' => 'array'        ];    }

使用樣本

   $user = new User;        $user->status = '1';        $user->score = '90.50';        $user->birthday = '2015/5/1';        $user->info = ['a'=>1,'b'=>2];        $user->save();    var_dump($user->status); // int 1    var_dump($user->score); // float 90.5;    var_dump($user->birthday); // string '2015-05-01 00:00:00'    var_dump($user->info);// array (size=2) 'a' => int 1  'b' => int 2

注意: 如果制定為時間戳記類型(timestamp)的話,該欄位會在寫入的時候自動調用strtotime函數產生對應的時間戳記,輸出是自動使用dateFormat格式化時間戳記,預設格式為Y:m:d H:i:s,如果想要改變輸出格式,可以如下:

   class User extends Model{        protected $dataFormat = 'Y/m/d';                protected $type = [                        'status' => 'integer',                        'score' => 'float',                        'birthday' => 'timestemp'//時間戳記格式        ];    }

或者如下:

   class User extends Model{               protected $type = [                       'status' => 'integer',                       'socre' => 'float',                       'birthday' => 'timestemp:Y/m/d'//寫入時間戳記,讀取按照Y/m/d的格式來格式化輸出。               ];       }


相關閱讀:

最詳細的ThinkPHP5自訂分頁類教程

thinkphp執行原生SQL語句的實現方法.

thinkphp5實現分頁功能的方法介紹

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.