一、 ThinkPHP简单工厂模式应用~之~根据数据库连接配置参数设定相应的数据库驱动类?
比如说当数据库类型'DB_TYPE'配置为'mysql',则ThinkPHP会自动建立MySQL的数据库连接。类似的,当'DB_TYPE'配置为'pgsql',则ThinkPHP会自动建立PgSQL的数据库连接。其他依次类推,ThinkPHP v3.2支持的数据库类型有:Firebird,Mongo,Mysql,Oracle,Pgsql,Sqlite,Sqlsrv。具体如何实现呢?
1、先来看下ThinkPHP源码目录结构中与数据库相关的类:
2、看完了目录结构,咱们就来扒一扒源码,看一看具体的实现细节:
// 1、首先,从调用开始说起。比如,想要操作用户表,那就先实现化一个用户模型类。
// 注:关于M()函数的更多解析,详见下文。
$user = M('User'); // 等效于 $user = new \Think\Model('User');
// 2、第1步实际上就是实例化了一个ThinkPHP的模型类(\thinkphp\Core\Library\Think\Model.class.php),这个模型类的构造方法中会调用类中的db()方法初始化数据库
namespace Think;
class Model {
public function __construct($name='',$tablePrefix='',$connection='') {
......
// 数据库初始化操作
// 获取数据库操作对象
// 当前模型有独立的数据库连接信息
$this->db(0,empty($this->connection)?$connection:$this->connection,true);
......
}
}
// 3、!!!重点来了!!!
// 下面这行代码就是通过“Db类(也就是工厂类)”根据数据库配置参数($config)实例化相应的数据库驱动类(产品类):比如,配置参数中的数据库类型'DB_TYPE'配置为'mysql',则会得到MySQL驱动类的实例化对象。
namespace Think;
class Model {
public function db($linkNum='',$config='',$force=false) {
......
$this->_db[$linkNum] = Db::getInstance($config);
......
}
}
// 4、当然,我们还可以继续看看“Db类(也就是工厂类)|\thinkphp\Core\Library\Think\Db.class.php”具体是如果根据数据库配置参数实例化相应的数据库驱动类(产品类)的。
namespace Think;
class Db {
static public function getInstance($config=array()) {
......
// 如果数据库配置参数中的数据库类型'DB_TYPE'(等于此处的$options['type'])配置为'mysql',则会实例化一个MySQL驱动类\Think\\Db\\Driver\\Mysql。
// MySQL驱动类对应的类文件是:\thinkphp\Core\Library\Think\Db\Driver\Mysql.class.php
$class = !empty($options['lite'])? 'Think\Db\Lite' : 'Think\\Db\\Driver\\'.ucwords(strtolower($options['type']));
if(class_exists($class)){
self::$instance[$md5] = new $class($options);
}
......
}
}
二、 除了工厂类可以生产产品类,PHP的函数是否也可以实现工厂类的相似功能呢?
答案是可以的,ThinkPHP就提供了两个函数用于实例化模型,这两个模型类实例化函数可以根据传入的不同参数生产出不同的模型类(产品类),或许我们可以称之为“工厂函数”。这两个“工厂函数”就是D()函数和M()函数,下面来看看它们的使用场景:
1、D()函数用于实例化自定义模型类
// 假设当前模块为Home模块,则可以这样来获取User用户模型类:
$user = D('User'); // 等效于 $user = new \Home\Model\UserModel();
// D方法还可以支持跨模块调用,比如在Home模块中需要实例化Admin模块的User模型:
$admin_user = D('Admin/User'); // 等效于 $admin_user = \Admin\Model\UserModel();
2、M()函数用于实例化默认模型类
// 使用M方法实例化默认的User用户模型类
$user = M('User'); // 等效于 $user = new \Think\Model('User');
// M方法实例化的时候,默认情况下是直接实例化系统的\Think\Model类,如果我们希望实例化其他的公共模型类的话,可以使用如下方法:
$user = M('\Home\Model\CommonModel:User','think_','db_config'); // 等效于 $user = new \Home\Model\CommonModel('User','think_','db_config');