ThinkPHP实现多数据库连接的解决方法


Posted in PHP onJuly 01, 2014

ThinkPHP实现连接多个数据的时候,如果数据库在同一个服务器里的话只需要这样定义模型:

class MembersModel extends Model{
protected $trueTableName = 'members.members'; //数据库名.表名(包含了前缀)
}

然后就可以像D("Members");这样实例化模型,像普通模型那样操作了。
但后来发现他的数据库在两个不同的服务器,这样上面的方法就不行了。
这时候就需要使用TP的多数据连接特性了。

对此,查阅官方文档进行测试并修正之后得出了如下的解决方法:

要建立多数据连接,首先要构造数据库配置参数。但是如果每次都在建立多数据库连接的时候都建立数据库配置数组,这样就会很麻烦,还不如写在配置文件里。这里怎么写还是需要有点技巧的。

<?php
$config= array(
'DEBUG_MODE'=>true,
'default_module'=>'Index',
'ROUTER_ON'=>TRUE,
'DATA_RESULT_TYPE'=>1,
'SHOW_RUN_TIME'=>true,   // 运行时间显示
'SHOW_ADV_TIME'=>true,   // 显示详细的运行时间
'SHOW_DB_TIMES'=>true,   // 显示数据库查询和写入次数
'SHOW_CACHE_TIMES'=>true,  // 显示缓存操作次数
'SHOW_USE_MEM'=>true,   // 显示内存开销
'HTML_FILE_SUFFIX'=>'.shtml',  // 默认静态文件后缀
'HTML_CACHE_ON' =>false,   // 默认关闭静态缓存
'HTML_CACHE_TIME'=>60,   // 静态缓存有效期
'HTML_READ_TYPE'=>1,   // 静态缓存读取方式 0 readfile 1 redirect
'HTML_URL_SUFFIX'=>'.shtml', // 伪静态后缀设置
//默认数据库链接
'DB_TYPE'=>'mysql',
'DB_HOST'=>'localhost',
'DB_NAME'=>'news',
'DB_USER'=>'root',
'DB_PWD'=>'123',
'DB_PORT'=>'3306',
'DB_PREFIX'=>'news_',
//我的第一个数据库连接
'DB_BBS'=>array(
'dbms' => 'mysql',
'username' => 'discuz',
'password' => '123',
'hostname' => 'localhost',
'hostport' => '3306',
'database' => 'discuz'
),
//第二个数据库链接,
'DB_NEWS'=>array(
'dbms'=>'mysql',
'username'=>'root',
'password'=>'123',
'hostname'=>'localhost',
'hostport'=>'3306',
'database'=>'news'
)
);
return $config;
?>

至此我们就可以用C("DB_BBS")和C("DB_NEWS")来得到数据库的配置数组。
配置好了,现在需要实例化模型。因为我们这个模型需使用两个不同的数据库的连接,项目的配置文件里默认了个数据库配置,如果你建立了某个表的模型比如UserModel.class.php,
如果你用D("User");但假如当前默认的数据库里没User个表的话就会报错。所以我们要建立个空模型。空模型是不会选表的。
有两种方法建立空模型。$dao=D();和$dao=new Model();都可以。

$dao=D();

实例化模型后,我们需要增加数据库模型;

$dao->addConnect(C("DB_BBS"),1,true);
$dao->addConnect(C("DB_NEWS"),2,true);

说一下这个addConnect();这个函数的原型在1.0.3和1.0.4是有区别的。
在1.0.3的原型是:

boolean addConnect (mixed $config, mixed $linkNum, [boolean $eqType = true])

在1.0.4的原型是:

boolean addConnect (mixed $config, mixed $linkNum)

少了第三个参数。
第一个参数是数据库的配置数组,第二个参数是添加的连接的编号,这个编号在切换数据库连接的时候需要给出是那个序号的连接。注意内置的数据库连接序号是0,所以额外的数据库连接序号应该从1开始.第三个参数是 如果两个数据库是否是相同的连接,是就是true;

添加完数据库连接后,就可以随时切换数据库连接了。比如我们这要用DB_NEWS这个数据库,就这么写:

$dao->switchConnect(2);

因为这里只是建立了数据库的连接,并没有选表,所以接下来需要选表。
注意这里的表名是全名,即表的前缀加表名。因为我们在连接数据库的配置数组里没前缀。我觉得应该可以定义,但我不知道。现在就这样了。

$dao->table("cdb_members");

之后就可以像普通模型一样的用这个模型了。
比如我要查询传递过来的ID的用户的所有信息 :

$map=array("id"=>$_GET["id"]);
$res=$dao->find($map);

可以看看查询是否成功了。

dump($res);

如果你现在要用DB_BBS的数据库的表,只需再切换一次连接;

$dao->switchConnect(2);

然后再选表查询。记住,切换模型后一定要再选一次表,不然会出错。
之后又可以像普通模型那样操作了。
下面针对手册指出里面存在的几处问题:

1.实例化多数据库连接的时候建立了个非空的模型。(好像还写错了。)这样可能会出错。建议建立空模型;
2.addConnect()的参数在不同的版本是不同的,手册中没写出来;
3.建立了空模型后需要选表,这个手册里没有。

针对以上几点,ThinkPHP使用者可以根据版本的不同酌情进行相应的调整。

希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助。

PHP 相关文章推荐
如何获得PHP相关资料
Oct 09 PHP
强烈推荐:php.ini中文版(2)
Oct 09 PHP
用windows下编译过的eAccelerator for PHP 5.1.6实现php加速的使用方法
Sep 30 PHP
PHP 面向对象程序设计(oop)学习笔记(三) - 单例模式和工厂模式
Jun 12 PHP
ThinkPHP的L方法使用简介
Jun 18 PHP
php基于Snoopy解析网页html的方法
Jul 09 PHP
php 修改上传文件大小限制实例详解
Oct 23 PHP
PHP使用星号替代用户名手机和邮箱的实现代码
Feb 07 PHP
thinkPHP中U方法加密传递参数功能示例
May 29 PHP
总结PHP代码规范、流程规范、git规范
Jun 18 PHP
浅谈laravel-admin form中的数据,在提交后,保存前,获取并进行编辑
Oct 21 PHP
PHP使用gearman进行异步的邮件或短信发送操作详解
Feb 27 PHP
ThinkPHP快速入门实例教程之数据分页
Jul 01 #PHP
ThinkPHP框架实现session跨域问题的解决方法
Jul 01 #PHP
ThinkPHP的模版中调用session数据的方法
Jul 01 #PHP
ThinkPHP的cookie和session冲突造成Cookie不能使用的解决方法
Jul 01 #PHP
ThinkPHP模板中判断volist循环的最后一条记录的验证方法
Jul 01 #PHP
PHP计算一年多少个星期和每周的开始和结束日期
Jul 01 #PHP
PHPMailer发送HTML内容、带附件的邮件实例
Jul 01 #PHP
You might like
Uncaught exception com_exception with message Failed to create COM object
2012/01/11 PHP
WIN8.1下搭建PHP5.6环境
2015/04/29 PHP
php+mysql实现无限级分类
2015/11/11 PHP
PHP MVC框架路由学习笔记
2016/03/02 PHP
php实现的SSO单点登录系统接入功能示例分析
2016/10/12 PHP
jquery tools 系列 scrollable学习
2009/09/06 Javascript
给jqGrid数据行添加修改和删除操作链接(之一)
2011/11/04 Javascript
jquery分页插件jpaginate在IE中不兼容问题
2014/04/22 Javascript
node.js中的fs.write方法使用说明
2014/12/15 Javascript
jQuery按需加载轮播图(web前端性能优化)
2017/02/17 Javascript
vue-resource调用promise取数据方式详解
2017/07/21 Javascript
jQuery实现百度图片移入移出内容提示框上下左右移动的效果
2018/06/05 jQuery
浅谈TypeScript 用 Webpack/ts-node 运行的配置记录
2019/10/11 Javascript
Antd的table组件表格的序号自增操作
2020/10/27 Javascript
一篇超完整的Vue新手入门指导教程
2020/11/18 Vue.js
基于element-ui封装表单金额输入框的方法示例
2021/01/06 Javascript
分析python服务器拒绝服务攻击代码
2014/01/16 Python
Python彩色化Linux的命令行终端界面的代码实例分享
2016/07/02 Python
Python DataFrame.groupby()聚合函数,分组级运算
2018/09/18 Python
Python实现定制自动化业务流量报表周报功能【XlsxWriter模块】
2019/03/11 Python
Pytorch 计算误判率,计算准确率,计算召回率的例子
2020/01/18 Python
Django models filter筛选条件详解
2020/03/16 Python
python使用yaml 管理selenium元素的示例
2020/12/01 Python
CSS实现鼠标滑过鼠标点击代码写法
2016/12/26 HTML / CSS
纯CSS3制作的简洁蓝白风格的登录模板(非IE效果更好)
2013/08/11 HTML / CSS
英国奢侈品网站:MatchesFashion
2016/12/16 全球购物
e路東瀛(JAPANiCAN)香港:日本旅游、日本酒店和温泉旅馆预订
2018/11/21 全球购物
优秀少先队大队辅导员事迹材料
2014/05/04 职场文书
先进个人事迹材料
2014/12/29 职场文书
社区扶贫帮困工作总结
2015/05/20 职场文书
幽默导游词应该怎么写?
2019/08/26 职场文书
详解Html5项目适配系统深色模式方案总结
2021/04/14 HTML / CSS
HTML5页面音频自动播放的实现方式
2021/06/21 HTML / CSS
vue如何实现关闭对话框后刷新列表
2022/04/08 Vue.js
Python中的matplotlib绘制百分比堆叠柱状图,并为每一个类别设置不同的填充图案
2022/04/20 Python
html网页引入svg图片的4种方式
2022/08/05 HTML / CSS