首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

ThinkPHP 模型實例化四大方式深度解析:從基礎 M() 到空模型與 D() 差異

     編輯:PHP 相關知識

ThinkPHP 模型實例化四大方式深度解析:從基礎 M() 到空模型與 D() 差異

ThinkPHP 提供了多種模型實例化方式,針對不同業務複雜度與架構需求。本文系統梳理四種核心方式的適用場景、代碼示例與底層機制差異,幫助開發者做出正確選型。

方式一:基礎模型實例化 —— 最常用

$user = new Model('user');  // 完整寫法
$user = M('user');          // 簡寫助手函數(推薦)
  • 適用:標準 CRUD、無自定義業務邏輯的通用表操作
  • 特點:自動映射表名(`think_user`)、無需創建模型類文件
  • 底層:`Think\Model` 基類實例化,緩存單例模式

方式二:公共模型繼承 —— 共享通用邏輯

<?php
// Common/Model/CommonModel.class.php
class CommonModel extends Model {
    // 定義通用方法:分頁、軟刪除、數據篩選等
    public function getPageList($where, $page, $size) { ... }
    public function softDelete($id) { ... }
}
?>

// 控制器中使用
$user = new CommonModel('user');  // 實例化 user 表,擁有 CommonModel 能力
$user->getPageList(['status'=>1], 1, 20);
  • 適用:多模型共享通用業務邏輯(如多租戶、軟刪除、審計日誌)
  • 優勢:避免代碼重複,統一規範數據訪問層行為

方式三:獨立模型類 —— 業務邏輯封裝

<?php
// Home/Model/UserModel.class.php
class UserModel extends Model {
    protected $_validate = [ ... ];  // 自動驗證
    protected $_auto     = [ ... ];  // 自動完成
    
    // 封裝業務方法
    public function register($data) { ... }
    public function login($username, $pwd) { ... }
    public function getProfile($uid) { ... }
}
?>

// 控制器中使用
$user = new UserModel();  // 無需傳表名,類名約定對應 user 表
$user->register($_POST);
  • 適用:業務邏輯複雜、需封裝驗證/完成/業務方法的核心模型
  • 優勢:職責單一、易測試、符合「胖模型、瘦控制器」原則

方式四:空模型 / 任意表操作 —— 最大靈活性

$model = new Model();  // 等價 M()
// 或
$model = M();
  • 特點:不綁定具體表,需手動指定表名或寫原生 SQL
  • 場景:
    • 動態表名:`$model->table('user_2023')->select()`
    • 多表聯合查詢:`$model->query('SELECT * FROM user u JOIN profile p ON u.id=p.uid')`
    • 臨時統計查詢:無需創建模型類的一次性操作

關鍵差異對比表

維度M('user')CommonModel('user')UserModel()M()/new Model()
綁定表useruseruser (約定)無 (動態指定)
自定義方法無繼承自 CommonModelUserModel 定義無
自動驗證/完成無CommonModel 定義UserModel 定義無
單例緩存是是是否 (每次 new)
推薦場景簡單 CRUD通用能力復用核心業務模型動態/臨時/多表

D() 方法特殊說明

$user = D('User');  // 注意大寫 U:對應 UserModel.class.php
  • 功能:自動檢測模型類是否存在 → 存在則實例化 UserModel,不存在則拋異常
  • 差異:`M()` 從不拋異常(無類則用基類);`D()` 強制要求模型類存在
  • 作用域:僅支持當前項目/應用下的模型類,跨模塊需完整命名空間

選型決策樹

需要封裝業務邏輯/驗證/完成?
  ├─ 是 → 創建 UserModel 類 → 用 D('User') 或 new UserModel()
  └─ 否 → 多模型共享通用方法?
        ├─ 是 → 創建 CommonModel → 用 new CommonModel('table')
        └─ 否 → 動態表名/多表/臨時查詢?
              ├─ 是 → 用 M() 或 new Model() + table()/query()
              └─ 否 → 簡單 CRUD → 用 M('table')

最佳實踐建議

  1. 項目初期:統一用 `M()` 快速開發
  2. 業務穩定後:核心模型遷移至 `UserModel` 類,用 `D()` 調用
  3. 通用能力(分頁、軟刪、範圍查詢)下沉到 `CommonModel`
  4. 避免在控制器寫原生 SQL,複雜查詢封裝到模型方法中
  5. ThinkPHP 6+ 建議使用依賴注入:`$this->app->make(UserModel::class)`

理解四種實例化方式的本質差異,能讓你在項目不同階段、不同模塊做出最合適的架構決策,避免「萬金油」模型類膨脹或重複造輪子。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved