thinkphp初探模型类(2)

来源:互联网 发布:ubuntu jdk rpm 安装 编辑:程序博客网 时间:2024/06/02 07:10

new Model

 之前弄清楚了字母方法M函数和D函数是如何寻找到Model文件,现在继续来了解一下tp框架是如何实例化一个Model类的。在数据库编程中,我可能不清楚每种语言对数据库操作的具体细节,但是所有的处理方式大方向上无非是4步,注册驱动,获取连接,进行操作,关闭连接。由于tp框架是采用驱动式设计的,这样的设计极大的简化了数据库连接过程中注册驱动的过程,下面来看一下tp框架是注册驱动并获取一个数据库连接的。
 Model类的实例化方式采取了面向对象中最简单的实例化方式,没有用到反射,也没有用到工厂模式,是简单粗暴地new出来的。为此,直接步入Model基类的构造方法,构造方法很短,只有二十行代码,可接收三个可选参数(模型名,表前缀,数据库链接信息),作用是定义模型名称以及表前缀,还有最后一行也是最重要的一行,对数据库的初始化操作。

$this->db(0,empty($this->connection)?$connection:$this->connection,true);

 这里第一个参数0代表的是数据库的编号,在切库操作起到了重要的作用,连接信息可有可无,有的话读连接信息,没有也会读配置的。最后一个参数设置为true代表着强制重新连接。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();        // 字段检测        if(!empty($this->name) && $this->autoCheckFields)    $this->_checkTableInfo();        return $this;    }

  这段代码并不难,而且还喜闻乐见地看到了static $_db = array();,通过缓存数组来提高程序运行效率已经深入人心了,这里就不多介绍了。下面的判断中不难理解,$force参数的作用,如果$force值为true,即使缓存数组存在该数据库实例,也要重新创建一个新实例。视野移至Db::getInstance($config);,Db类是tp框架数据库连接层的一个中间实现类,他的作用是用来为完成数据库驱动类的实例化操作,最终返回数据库的驱动类,也就是4部曲中的注册驱动的过程。来看看这段代码具体都干了啥。

 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;    }

 第一行代码的作用就是上面说烂了的有值就读值,没有就读配置。下面的代码先去找数据库的类型,之后通过数据库的类型,去寻找数据库驱动文件,可以很明显的看到驱动文件都在Think\Db\Driver\文件夹下,最后检查驱动类是否存在,存在的话便实例化驱动类,并完成连接工作(这里面的操作无非是new mysqli之类的),不存在则抛出异常,最后返回数据库类实例。整个实例化的操作代码并不复杂,如果理解这个过程对之后的Model切库操作有很大帮助。

0 0
原创粉丝点击