# ThinkPHP6.0 模型
模型會自動對應數據表,模型類的命名規則是除去表前綴的數據表名稱,采用駝峰法命名,并且首字母大寫.
* * *
## ThinkPHP6 模型
* 請確保你已經在數據庫配置文件中配置了數據庫連接信息
* 模型會自動對應數據表,模型類的命名規則是除去表前綴的數據表名稱,采用駝峰法命名,并且首字母大寫
* 模型自動對應的數據表名稱都是遵循小寫+下劃線規范,如果你的表名有大寫的情況,必須通過設置模型的table屬性。
## 一、創建模型
模型名數據庫前綴Catshop_catGoods shop_goodsUserOrder shop_user_order
表前綴設置:`config/database.php`文件里`prefix`
* 第一步:創建一個跟控制器平級的目錄,目錄名:`model`
* 第二步:在`model`創建`Goods.php`文件
## 二、模型操作
在模型中除了可以調用數據庫類的方法之外(換句話說,數據庫的所有查詢構造器方法模型中都可以支持),可以定義自己的方法,所以也可以把模型看成是數據庫的增強版
* 模型文件里的自定義方法,不要和 thinkphp 方法一樣名稱
* 模型里的`Goods::`也可以用`static::`關鍵詞
* 鏈式操作,都可以在模型里使用
1、`find`查詢數據
find 獲取單條數據,返回的是當前模型的對象實例
> namespace app\\model;
>
> use think\\Model;
>
> class Goods extends Model{
>
> ? ? public function find(){
>
> ? ? ? ? $find = Goods::find(6);
>
> ? ? ? ? $find = Goods::where('id',7)->find();
>
> ? ? ? ? return $find;
>
> ? ? }
>
> }
2、`controller`怎么調用`model`
> namespace app\\controller;
>
> use app\\model\\Goods;
>
> class Index{
>
> ? ? public function index(){
>
> ? ? ? ? $db = new Goods();
>
> ? ? ? ? $index = $db->find();
>
> ? ? ? ? print\_r($index);
>
> ? ? }
>
> }
find(6) 查詢失敗,是因為數據庫主鍵名稱不是 id
3、`select`查詢數據
select 獲取多條數據,返回的是當前模型的對象實例
> public function select(){
>
> ? ? $select = Goods::select();
>
> ? ? $select = Goods::select(6);
>
> ? ? $select = Goods::where('id','>',7)->select();
>
> ? ? return $select;
>
> }
4、數據轉換
`toArray`方法將當前的模型實例輸出為數組
> public function select(){
>
> ? ? $select = Goods::select();
>
> ? ? $select = Goods::select(6);
>
> ? ? $select = Goods::where('id','>',7)->select();
>
> ? ? return $select->toArray();
>
> }
5、增加數據
* `create`靜態方法添加數據,返回的是當前模型的對象實例
> public function create(){
>
> ? ? $create = Goods::create(\[
>
> ? ? ? ? 'cat' =>? 3,
>
> ? ? ? ? 'title' =>? '新商品',
>
> ? ? ? ? 'price' =>? '59.99',
>
> ? ? ? ? 'add\_time' => time()
>
> ? ? \]);
>
> ? ? echo $create->id;? // 可以直接獲取自增id
>
> ? ? return $create;
>
> }
新增數據的最佳實踐原則:使用create方法新增數據,使用saveAll批量新增數據。
6、修改數據
* `update`靜態方法修改數據,返回的是當前模型的對象實例
* `save`在取出數據后,更改字段更新數據。這種方式是最佳的更新方式
> namespace app\\model;
>
> use think\\Model;
>
> class Goods extends Model{
>
> ? ? public function update(){
>
> ? ? ? ? # 更新方式1
>
> ? ? ? ? $update = Goods::update(
>
> ? ? ? ? ? ? \['price'=>'99.99'\],
>
> ? ? ? ? ? ? \['id'=>22\]
>
> ? ? ? ? );
>
> ? ? ? ? return $update;
>
> ? ? ? ? # 更新方式2
>
> ? ? ? ? $user = Goods::find(23);
>
> ? ? ? ? $user->price? ? ?= '102.99';
>
> ? ? ? ? $save = $user->save();
>
> ? ? ? ? return $save;
>
> ? ? }
>
> }
7、刪除數據
* `delete`靜態方法刪除數據,返回的是當前模型的對象實例
* `destroy`根據主鍵刪除
> public function delete(){
>
> ? ? # 刪除方法1
>
> ? ? $delete = Goods::where('id',3)->delete();
>
> ? ? # 刪除方法2
>
> ? ? $delete = User::destroy(4);
>
> ? ? return $delete;
>
> }
TP模型如果只能增刪查改,不如在`Controller`執行了。TP模型很多特點,下面為大家一一介紹
## 三、模型設置
為了和數據庫更好的適配,模型可以提前設置對應的數據庫屬性,一個文件配置一個數據表
屬性描述name 模型名(相當于不帶數據表前后綴的表名,默認為當前模型類名)table 數據表名(默認自動獲取)pk 主鍵名(默認為 id )schema 模型對應數據表字段及類型type 模型需要自動轉換的字段及類型disuse 數據表廢棄字段(數組)
?1、name和table
當你的數據表沒有前綴的時候,name和table屬性的定義是沒有區別的,定義任何一個即可
> class Goods extends Model{
>
> ? ? protected $name = 'Goods';
>
> ? ? protected $table = 'shop\_goods';
>
> ? ? public function select(){
>
> ? ? ? ? $select = Goods::select();
>
> ? ? ? ? return $select->toArray();
>
> ? ? }
>
> }
2、pk 改變主鍵名稱
model 默認的主鍵是id
> // 可以把主鍵改為shop\_id 試試
>
> ALTER TABLE `ouyangke`.`shop\_goods`?
>
> CHANGE COLUMN `id` `shop\_id` int(10) UNSIGNED NOT NULL AUTO\_INCREMENT COMMENT ' 商品ID' FIRST,
>
> DROP PRIMARY KEY,
>
> ADD PRIMARY KEY (`shop\_id`) USING BTREE;
>
> class Goods extends Model{
>
> ? ? protected $name = 'Goods';
>
> ? ? protected $table = 'shop\_goods';
>
> ? ? protected $pk = 'shop\_id';
>
> ? ? public function find($id=1){
>
> ? ? ? ? $find = Goods::find($id);
>
> ? ? ? ? return $find->toArray();
>
> ? ? }
>
> }
3、`schema`設置模型對應數據表字段及類型
* 默認會自動獲取(包括字段類型),但自動獲取會導致增加一次查詢
* schema 屬性一旦定義,就必須定義完整的數據表字段類型
* 類型根據php數據類型定義,如果是json類型直接定義為json即可
> class Goods extends Model{
>
> ? ? protected $name = 'Goods';
>
> ? ? protected $table = 'shop\_goods';
>
> ? ? protected $pk = 'shop\_id';
>
> ? ? protected $schema = \[
>
> ? ? ? ? 'shop\_id' => 'int',
>
> ? ? ? ? 'cat' => 'int',
>
> ? ? ? ? 'title' => 'string',
>
> ? ? ? ? 'price' => 'float',
>
> ? ? ? ? 'discount' => 'int',
>
> ? ? ? ? 'stock' => 'int',
>
> ? ? ? ? 'status' => 'int',
>
> ? ? ? ? 'add\_time' => 'int'
>
> ? ? \];
>
> ? ? # 對某個字段定義需要自動轉換的類型,可以使用type屬性
>
> ? ? protected $type = \[
>
> ? ? ? ? 'shop\_id' => 'int'
>
> ? ? \];
>
> ? ? public function select(){
>
> ? ? ? ? $select = Goods::select();
>
> ? ? ? ? return $select->toArray();
>
> ? ? }
>
> }
4、`disuse`數據表廢棄字段(數組)
> class Goods extends Model{
>
> ? ? protected $name = 'Goods';
>
> ? ? protected $table = 'shop\_goods';
>
> ? ? protected $pk = 'shop\_id';
>
> ? ? protected $disuse = \[
>
> ? ? ? ? 'discount',
>
> ? ? ? ? 'stock'
>
> ? ? \];
>
> ? ? public function select(){
>
> ? ? ? ? $select = Goods::select();
>
> ? ? ? ? return $select->toArray();
>
> ? ? }
>
> }
5、其他屬性(不常用)
屬性描述suffix 數據表后綴(默認為空)connection 數據庫連接(默認讀取數據庫配置)query 模型使用的查詢類名稱field 模型允許寫入的字段列表(數組)strict 是否嚴格區分字段大小寫(默認為 true )readonly 字段只讀json 設置字段為JSON數據jsonType 設置JSON字段的類型jsonAssoc 設置JSON數據返回數組autoWriteTimestamp 自動寫入創建和更新的時間戳字段(默認關閉)createTime 創建時間戳字段updateTime 更新時間戳字段deleteTime 用于定義你的軟刪除標記字段defaultSoftDelete 定義軟刪除字段的默認值
## 四、模型 主要功能
1、獲取器
* 獲取器的作用是對模型實例的(原始)數據做出自動處理
* 命名規則:`get + 字段名 + Attr`
* 字段名是數據表字段的駝峰轉換
> class Goods extends Model{
>
> ? ? public function index(){
>
> ? ? ? ? $find = Goods::find(10);
>
> ? ? ? ? echo $find->status;
>
> ? ? ? ? return $find->toArray();
>
> ? ? }
>
> ? ? public function getStatusAttr($v){
>
> ? ? ? ? $status = \[
>
> ? ? ? ? ? ? 1=>'開啟',
>
> ? ? ? ? ? ? 2=>'關閉'
>
> ? ? ? ? \];
>
> ? ? ? ? return $status\[$v\];
>
> ? ? }
>
> }
2、修改器
* 修改器的主要作用是對模型設置的數據對象值進行處理
* 命名規則:`set + 字段名 + Attr`
> class Goods extends Model{
>
> ? ? public function index(){
>
> ? ? ? ? $create = Goods::create(\[
>
> ? ? ? ? ? ? 'cat' =>? 3.33,
>
> ? ? ? ? ? ? 'title' =>? '新商品',
>
> ? ? ? ? ? ? 'price' =>? '59.99',
>
> ? ? ? ? ? ? 'add\_time' => time()
>
> ? ? ? ? \]);
>
> ? ? ? ? return $create;
>
> ? ? }
>
> ? ? public function setCatAttr($v,$all){
>
> ? ? ? ? // $all 全部參數
>
> ? ? ? ? return (int)$v;
>
> ? ? }
>
> }
3、搜索器
* 搜索器的作用是用于封裝字段(或者搜索標識)的查詢條件表達式
* 命名規則:`search + 字段名 + Attr`
> class Goods extends Model{
>
> ? ? public function index(){
>
> ? ? ? ? $select = Goods::withSearch(\['title'\],\[
>
> ? ? ? ? ? ? 'title' => '新'
>
> ? ? ? ? \])->select();
>
> ? ? ? ? return $select->toArray();
>
> ? ? }
>
> ? ? public function searchTitleAttr($query,$v){
>
> ? ? ? ? $query->where('title','like', $v . '%');
>
> ? ? }
>
> }
4、檢查數據
* 如果要判斷數據集是否為空,不能直接使用`empty`判斷
* 必須使用數據集對象的`isEmpty`方法判斷
> class Goods extends Model{
>
> ? ? public function index(){
>
> ? ? ? ? $select = Goods::where('title','1')->select();
>
> ? ? ? ? if(empty($select)){
>
> ? ? ? ? ? ? echo 111;
>
> ? ? ? ? }
>
> ? ? ? ? if($select->isEmpty()){
>
> ? ? ? ? ? ? echo 111;
>
> ? ? ? ? }
>
> ? ? }
>
> }
## 五、右側列表改為model示例
model代碼
> namespace app\\model;
>
> use think\\Model;
>
> use think\\facade\\Db;
>
> class Goods extends Model{
>
> ? ? protected $name = 'Goods';
>
> ? ? protected $table = 'shop\_goods';
>
> ? ? public function get\_all($where,$order='add\_time DESC',$p=1,$total=10){
>
> ? ? ? ? $count = Goods::where($where)->count();
>
> ? ? ? ? $list = Goods::where($where)
>
> ? ? ? ? ? ? ? ? ? ? ->order($order)
>
> ? ? ? ? ? ? ? ? ? ? ->page($p,$total)
>
> ? ? ? ? ? ? ? ? ? ? ->select();
>
> ? ? ? ? if($list->isEmpty()){
>
> ? ? ? ? ? ? return null;
>
> ? ? ? ? }
>
> ? ? ? ? $data = $list->toArray();
>
> ? ? ? ? foreach($data as &$data\_v){
>
> ? ? ? ? ? ? $data\_v\['cat'\] = Db::table('shop\_cat')->where('id',$data\_v\['cat'\])->value('name');
>
> ? ? ? ? }
>
> ? ? ? ? $arr = \[
>
> ? ? ? ? ? ? 'count' => ceil($count/$total),
>
> ? ? ? ? ? ? 'data' => $data
>
> ? ? ? ? \];
>
> ? ? ? ? return $arr;
>
> ? ? }
>
> ? ? public function getStatusAttr($v){
>
> ? ? ? ? $status = \[
>
> ? ? ? ? ? ? 1=>'開啟',
>
> ? ? ? ? ? ? 2=>'關閉'
>
> ? ? ? ? \];
>
> ? ? ? ? return $status\[$v\];
>
> ? ? }
>
> ? ? public function getAddTimeAttr($v){
>
> ? ? ? ? return date('Y-m-d',$v);
>
> ? ? }
>
> }
controller代碼
> public function index(){
>
> ? ? $title = '商城';
>
> ? ? $login = '歐陽克';
>
> ? ? # 左側菜單
>
> ? ? $menu = Db::table('shop\_menu')->where('fid',0)->select();
>
> ? ? $left = \[\];
>
> ? ? foreach($menu as $menu\_k=>$menu\_v){
>
> ? ? ? ? $left\[$menu\_k\] = $menu\_v;
>
> ? ? ? ? $left\[$menu\_k\]\['lists'\] = Db::table('shop\_menu')->where('fid',$menu\_v\['id'\])->select();
>
> ? ? }
>
> ? ? # 右側列表
>
> ? ? $param = Request::param();
>
> ? ? if(isset($param\['status'\]) && $param\['status'\] == 1){
>
> ? ? ? ? $where\['status'\] = 1;
>
> ? ? }else if(isset($param\['status'\]) && $param\['status'\] == 2){
>
> ? ? ? ? $where\['status'\] = 2;
>
> ? ? }else{
>
> ? ? ? ? $where = true;
>
> ? ? }
>
> ? ? $p = isset($param\['p'\]) ? $param\['p'\] : 1;
>
>
>
> ? ? $db = new Goods();
>
> ? ? $order = \[
>
> ? ? ? ? 'add\_time DESC',
>
> ? ? ? ? 'id DESC'
>
> ? ? \];
>
> ? ? $right = $db->get\_all($where,$order,$p,5);
>
> ? ? View::assign(\[
>
> ? ? ? ? 'title'? => $title,
>
> ? ? ? ? 'login' => $login,
>
> ? ? ? ? 'left' => $left,
>
> ? ? ? ? 'right' => $right\['data'\],
>
> ? ? ? ? 'count' => $right\['count'\],
>
> ? ? ? ? 'p' => $p,
>
> ? ? ? ? 'status' => isset($param\['status'\]) ? $param\['status'\] : 0
>
> ? ? \]);
>
> ? ? return View::fetch();
>
> }
html代碼
> {$right\_v.status}
>
> {$right\_v.add\_time}
## 六、模型事件
* 模型事件是指在進行模型的查詢和寫入操作的時候觸發的操作行為
* 模型事件只在調用模型的方法生效,使用查詢構造器操作是無效的
編號事件描述事件方法名1after_read查詢后 onAfterRead2 before_insert 新增前onBeforeInsert3 after_insert 新增后onAfterInsert4before_update 更新前onBeforeUpdate5 after_update 更新后onAfterUpdate6 before_write 寫入前onBeforeWrite7 after_write 寫入后onAfterWrite8 before_delete 刪除前onBeforeDelete9 after_delete 刪除后onAfterDelete10 before_restore 恢復前onBeforeRestore11 after_restore 恢復后onAfterRestore
~~~
namespace?app\model;
use?think\Model;
class?Goods?extends?Model{
????public?function?one_update(){
????????$update?=?Goods::update(
????????????['price'=>'99.99'],
????????????['id'=>22]
????????);
????????return?$update;
????}
????#?執行更新操作,就會之下onBeforeUpdate方法
????public?static?function?onBeforeUpdate($goods){
????????print_r($goods->price);
????????return?true;
????}
}
~~~