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


一、實例化模型

  在ThinkPHP2.0及以上版本中,可以無需進行任何模型定義。只有在需要封裝單獨的業務邏輯時,模型類才是必須定義的,因此ThinkPHP在模型上有很多靈活性和方便性,而不必因為表太多而煩惱

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

  1、實例化基礎模型類  

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

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

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

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

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

  User                  think_user

  UserMessage               think_user_message

  ps,因為表前綴中已經有了一個下划線,所以user對應的也是think_user

  2、實例化其它模型類

  第一種實例化方法因為沒有涉及自定義模型類,因此很難封裝一些自定義的業務邏輯(因為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操作的話,只是個別模型有一些復雜的業務邏輯需要封裝,那么第一種方式和第二種方式的結合是一個不錯的選擇。

  3、實例化自定義模型類

  得先定義針對不同表的自定義模型類,比如說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操作,還想用到一些自定義的邏輯操作,而且這些邏輯操作只有該表用到(即不需要用到其它表通用的自定義邏輯操作),則采用第三種方式

  4、實例化一個空模型類

  如果僅僅是想使用原生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>的,從而導致顯示一片空白二、模型命名和獲取字段

  1、關於模型命名

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

    ·$tableName

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

    ·$trueTableName

    包含表前后綴的數據表名稱,默認為null,即數據庫中的真實表名

  經過測試,三者的優先級應該如下

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

  也就是說設置了$trueTableName就按$trueTableName的來,否則按$tableName、最后按默認的

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

  關於表后綴,手冊上說的一段話如下

  

  2、獲取字段

  

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

  

    ·ThinkPHP的默認認為數據表的主鍵字段名都是id,並且自動增長

    ·$User->getPk();可以獲取User表的主鍵

    ·$User->getDbFields();可以獲取User表的所有字段信息


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM