ThinkPHP教程_PHP框架之ThinkPHP(六)【實例化模型、模型命名和獲取字段】

1、實例化模型php

  在ThinkPHP2.0及以上版本中,能夠無需進行任何模型定義。只有在須要封裝單獨的業務邏輯時,模型類纔是必須定義的,所以ThinkPHP在模型上有不少靈活性和方便性,而沒必要由於表太多而煩惱數據庫

  ThinkPHP有幾種實例化模型的方法緩存

  一、實例化基礎模型類  框架

  即實例化系統自帶的Model類,ThinkPHP會自動幫咱們找到數據庫中相應的表,並獲取其字段(表結構信息)函數

    ·$User=new Model('User');測試

    ·$User=M('User');(快捷方法,經過M()函數)ui

  大寫字母與下劃線關係(think_是在配置文件中設置的表前綴)spa

  實例化基礎模型類傳遞進去的參數    在數據庫中對應的表名設計

  User                  think_user調試

  UserMessage               think_user_message

  ps,由於表前綴中已經有了一個下劃線,因此user對應的也是think_user

  二、實例化其它模型類

  第一種實例化方法由於沒有涉及自定義模型類,所以很難封裝一些自定義的業務邏輯(由於ThinkPHP自帶的基礎模型類顯然只提供了基本的CRUD操做等等一些操做,確定是沒法知足項目業務邏輯的,因此必須自定義模型類來封裝自定義業務邏輯),若是隻須要擴展一些通用的(所謂通用,就是多個針對不一樣表的模型類都須要用到的邏輯)自定義業務邏輯,那麼能夠採用這種方式

    ·$User=new CommonModel('User');

    ·$User=M('User','CommonModel');(快捷方式,經過M()函數)

    ps,CommonModel類是一個自定義模型類,在應用目錄->Lib目錄->Model目錄->CommonModel.class.php文件

  由於ThinkPHP是自動加載模型類的,因此在實例化模型類以前不須要手動模型類文件的導入,即不須要require '模型類文件';等

  自定義模型類必須繼承系統自帶的模型類(好比說Model類),並且沒有別名導入的話,自定義模型類文件必須放在應用目錄->Lib目錄->Model目錄

  能夠在CommonModel類裏面定義一些通用的邏輯方法,就能夠省去爲每一個數據表定義具體的模型類,若是你的項目已經有超過100個數據表了,而大多數狀況都是一些基本的CURD操做的話,只是個別模型有一些複雜的業務邏輯須要封裝,那麼第一種方式和第二種方式的結合是一個不錯的選擇。

  三、實例化自定義模型類

  得先定義針對不一樣表的自定義模型類,好比說UserModel類,UserMessagesModel類等等,而後再進行實例化。這種方式是用的最多的

    ·$User=new UserModel;

    ·$User=D('User');(快捷方式,經過D()函數),D()函數有自動檢測自定義模型類的功能,若是應用目錄->Lib目錄->Model目錄下存在所傳入參數對應的自定義模型類(即參數User對應於自定義模型類UserModel),那麼就會實例化該自定義模型類,不然則實例話系統自帶的模型類(Model類)。並且對於已經實例化過的模型不會重複實例化,默認的D()函數只能實例化當前應用的模型類,不能跨應用實例化模型類,若是想實例化其它應用的模型類,則能夠$User=D('User','其它應用名');,若是啓用了模塊分組,則能夠$Usr=D('其它分組名.User');

  ps,這種實例化模型方式與上一種方式有何區別,其實上一種方式最大的特徵就是通用。對於一張表,若是你只想對其進行簡單的CRUD操做,則採用第一種方式便可;若是你不只想對其進行簡單的CRUD操做,還想用到一些該項目其它表通用的自定義邏輯操做,則採用第二種方式;若是不只想對其進行CRUD操做,還想用到一些自定義的邏輯操做,並且這些邏輯操做只有該表用到(即不須要用到其它表通用的自定義邏輯操做),則採用第三種方式

  四、實例化一個空模型類

  若是僅僅是想使用原生SQL的話,不須要使用額外的模型類,能夠選擇實例化一個空模型類

    ·$Model=new Model();

    ·$Model=M();(快捷方式,經過M()函數)

  好比說$Model->query('SELECT * FROM think_user where status=1');

 

  不論是採用哪種方式,以及不論是採用new、M()或者D()進行實例化模型類,都會ThinkPHP都會自動加載數據庫鏈接信息去鏈接數據庫,若是數據庫鏈接失敗也是會報錯的

  關於數據表字段緩存,索引表示表字段,關聯表示表的一些屬性

  

  若是開啓數據表字段緩存,則ThinkPHP是不理會任何有關表結構的修改操做的,也就是說,即便修改了表結構,ThinkPHP也會按照數據表字段緩存文件中的表結構對錶進行操做,除非手動刪除數據表字段緩存文件。那麼不難看出(並通過測試),ThinkPHP的數據表字段緩存機制是這樣的,在進行數據庫操做以前,先判斷是否開啓數據表字段緩存,若是開啓,則檢索一下應用目錄->Runtime目錄->Data目錄->_field目錄中有無相應表的數據表字段緩存文件,如有,則加載該文件中的表結構,而後對相應表進行操做,若無,則先操做數據庫獲取到表結構,而後再對相應表進行操做,並將剛纔獲取到的表結構緩存起來;若是沒有開啓則直接先操做數據庫獲取表結構,而後再對相應表進行操做!這段話能夠簡化成以下代碼,O(∩_∩)O哈哈~

  

  當開啓APP_DEBUG(調試模式)以後,模板中的框架集就不能顯示了!這是由於Trace等信息是放在<body>中的,而框架集中是不能存在<body>的,從而致使顯示一片空白2、模型命名和獲取字段

  一、關於模型命名

  到這裏,基本是已經明確了自定義模型名與數據表名之間的對應關係。也就是說,自定義模型類會根據去名稱其對相應的表進行操做,那麼假如要求自定義模型類不根據其表名對相應的數據表進行操做該怎麼辦呢(即跨表操做)?答案是能夠經過Model類的以下兩個屬性(protected屬性)進行操做

    ·$tableName

    不包含表先後綴的數據表名稱,與自定義模型類名(或自帶的模型類中實例化時傳入的參數)相對應,可是能夠修改該屬性,來讓自定義模型類操做與其名稱不對應的表

    ·$trueTableName

    包含表先後綴的數據表名稱,默認爲null,即數據庫中的真實表名

  通過測試,三者的優先級應該以下

  自定義模型類中本身指定的$trueTableName>自定義模型類中本身指定的$tableName>ThinkPHP自帶的模型類中默認的$tableName

  也就是說設置了$trueTableName就按$trueTableName的來,不然按$tableName、最後按默認的

  除了能夠對默認的數據表進行修改以外還能夠對默認的數據庫進行修改,使用$dbName屬性!只有在當前的模型類對應的數據庫名稱和配置文件不一樣的時候才須要定義,以實現跨庫操做

  關於表後綴,手冊上說的一段話以下

  

  二、獲取字段

  

  關於這段邏輯,不知道有想法的同志有沒有思考過,就是對數據表進行操做以前必要進行這樣的判斷和文件加載等等操做嗎?爲啥不直接將表結構信息告訴模型,那麼就省去了這麼多麻煩,直接對數據表就能夠進行操做,顯然節省IO開銷,而且省掉一次查詢數據庫獲取表結構的數據庫操做,提高效率!對,ThinkPHP的設計者也考慮到了這一點,就設計了$field屬性

  

    ·ThinkPHP的默認認爲數據表的主鍵字段名都是id,而且自動增加

    ·$User->getPk();能夠獲取User表的主鍵

    ·$User->getDbFields();能夠獲取User表的全部字段信息

相關文章
相關標籤/搜索