thinkphp的M方法小結

  M方法是TP中最多見的一個模型化沒有文件的Model方法。仔細進行解析的時候,會發現裏面邏輯也是挺多的,這節主要梳理TP框架最多見的M方法。
  方法代碼:
  function M($name='', $tablePrefix='',$connection='') {
    //設立一個靜態變量,能夠在運行過程當中,一直保存的值
    static $_model  = array();
    //若是在裏面找到了:號,就用explode進行分割提取,不然就讀取model
    if(strpos($name,':')) {
  //M方法實例化的時候,默認狀況下是直接實例化系統的\Think\Model類,
  //示例M('\Home\Model\CommonModel:User','think_','db_config');這種通常用的比較少,大多數狀況下用Think\\Model
        list($class,$name)    =  explode(':',$name);
    }else{
      // 默認的class就是
        $class      =   'Think\\Model';
    }
    //鏈接標記數組標記
    $guid     =   (is_array($connection)?implode('',$connection):$connection).$tablePrefix . $name . '_' . $class;
    //沒有模型化將緩存裏面的對象返回出來
    if (!isset($_model[$guid]))
        $_model[$guid] = new $class($name,$tablePrefix,$connection);
    return $_model[$guid];
}
運行邏輯:檢測是否是實例化默認的類,將其放入一個$_model數組中,並給每一個實例化都賦予一個鍵值。
默認執行的類是:
$a = new \Think\Model();
實例化的時候__construct()
 public function __construct($name='',$tablePrefix='',$connection='') {
       //在自動加載的時候,實現自動初始化,能夠加入用戶本身的斷定邏輯
        $this->_initialize();
         if(!empty($name)) {
            if(strpos($name,'.')) {
        // 支持 數據庫名.模型名的 定義
                list($this->dbName,$this->name) = explode('.',$name);
            }else{
                $this->name   =  $name;
            }
        }elseif(empty($this->name)){
            $this->name =   $this->getModelName();
        }
        // 設置表前綴
        if(is_null($tablePrefix)) {// 前綴爲Null表示沒有前綴
            $this->tablePrefix = '';
        }elseif('' != $tablePrefix) {
            $this->tablePrefix = $tablePrefix;
        }elseif(!isset($this->tablePrefix)){
            $this->tablePrefix = C('DB_PREFIX');
        }
        // 數據庫初始化操做
        // 獲取數據庫操做對象
        // 當前模型有獨立的數據庫鏈接信息
        $this->db(0,empty($this->connection)?$connection:$this->connection,true);
    }
自動加載運行邏輯:初始化模型,將輸入的字段儲存到$this->name和$this->db,而後讀取鏈接信息

默認的數據庫鏈接,數據庫的鏈接配置
    public function db($linkNum='',$config='',$force=false) {
        if('' === $linkNum && $this->db) {
            return $this->db;
        }
        static $_db = array();
        if(!isset($_db[$linkNum]) || $force ) {
            // 建立一個新的實例
            if(!empty($config) && is_string($config) && false === strpos($config,'/')) { // 支持讀取配置參數
                $config  =  C($config);
            }
            $_db[$linkNum]            =    Db::getInstance($config);
        }elseif(NULL === $config){
            $_db[$linkNum]->close(); // 關閉數據庫鏈接
            unset($_db[$linkNum]);
            return ;
        }

        // 切換數據庫鏈接
        $this->db   =    $_db[$linkNum];
        $this->_after_db();
        // 字段檢測,能夠經過DB_FIELDS_CACHE控制是否緩存數據庫的字段(常常變更字段的,應該禁止掉該參數)
        if(!empty($this->name) && $this->autoCheckFields)    $this->_checkTableInfo();
        return $this;
    }
運行邏輯:建立一個配置,切換數據庫鏈接,每次都讀取配置裏面的配置信息進行實例化變更

獲取數據庫的實例:
    public static function getInstance($db_config='') {
        static $_instance    =    array();
        //生成一個惟一的鍵值,用儲存
        $guid    =    to_guid_string($db_config);
        if(!isset($_instance[$guid])){
            $obj    =    new Db();
            $_instance[$guid]    =    $obj->factory($db_config);
        }
        return $_instance[$guid];
    }

加載驅動進行控制:
 public function factory($db_config='') {
        // 讀取數據庫配置
        $db_config = $this->parseConfig($db_config);
        if(empty($db_config['dbms']))
            E(L('_NO_DB_CONFIG_'));
        // 數據庫類型
        if(strpos($db_config['dbms'],'\\')){
            $class  =   $db_config['dbms'];
        }else{
            $dbType =   ucwords(strtolower($db_config['dbms']));
            $class  =   'Think\\Db\\Driver\\'. $dbType;            
        }
        // 檢查驅動類
        if(class_exists($class)) {
            $db = new $class($db_config);
        }else {
            // 類沒有定義
            E(L('_NO_DB_DRIVER_').': ' . $class);
        }
        return $db;
    }
運行邏輯:根據配置讀取對應的數據庫控制驅動(經常使用的mysql或者mysqli驅動等)
整理後M的運行邏輯流程以下:(M('user')流程)
實例化model-》自動加載實現(獲取到name,dbname,db等)——》$this->db根據當前配置去實例化對應的Db類
——》Db類里根據當前的配置去找到對應的數據庫驅動,同時進行實例化返回——》返回$this,進行其餘的操做
M的幾種用法展現:
1.$Model = M();
//進行原生的SQL查詢
$Model->query('SELECT * FROM think_user WHERE status = 1');
2.M('\Home\Model\CommonModel:User','think_','db_config');mysql

相關文章
相關標籤/搜索