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中for循环语句的几种变型
Mar 16 PHP
网页游戏开发入门教程三(简单程序应用)
Nov 02 PHP
php事务处理实例详解
Jul 11 PHP
php猴子选大王问题解决方法
May 12 PHP
php实现倒计时效果
Dec 19 PHP
php 实现进制相互转换
Apr 07 PHP
PHP入门教程之PHP操作MySQL的方法分析
Sep 11 PHP
iOS10推送通知开发教程
Sep 19 PHP
ThinkPHP中类的构造函数_construct()与_initialize()的区别详解
Mar 13 PHP
微信接口生成带参数的二维码
Jul 31 PHP
[原创]php token使用与验证示例【测试可用】
Aug 30 PHP
TP3.2.3框架使用CKeditor编辑器在页面中上传图片的方法分析
Dec 31 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
应用开发中涉及到的css和php笔记分享
2011/08/02 PHP
php上传文件常见问题总结
2015/02/03 PHP
基于CakePHP实现的简单博客系统实例
2015/06/28 PHP
php 利用socket发送HTTP请求(GET,POST)
2015/08/24 PHP
Ajax实现对静态页面的文章访问统计功能示例
2016/10/10 PHP
仿jQuery的siblings效果的js代码
2011/08/09 Javascript
checkbox全选所涉及到的知识点介绍
2013/12/31 Javascript
jquery中ajax函数执行顺序问题之如何设置同步
2014/02/28 Javascript
connect中间件session、cookie的使用方法分享
2014/06/17 Javascript
javascript实现点击按钮弹出一个可关闭层窗口同时网页背景变灰的方法
2015/05/13 Javascript
AngularJS的表单使用详解
2015/06/17 Javascript
jquery实现的横向二级导航效果代码
2015/08/26 Javascript
js全选按钮的实现方法
2015/11/17 Javascript
jQuery控制frames及frame页面JS的方法
2016/03/08 Javascript
Three.js利用orbit controls插件(轨道控制)控制模型交互动作详解
2017/09/25 Javascript
基于jQuery中ajax的相关方法汇总(必看篇)
2017/11/08 jQuery
JavaScript常见事件对象与操作实例总结
2019/01/05 Javascript
jQuery实现移动端下拉展现新的内容回弹动画
2020/06/24 jQuery
python实现批量改文件名称的方法
2015/05/25 Python
玩转python爬虫之正则表达式
2016/02/17 Python
详谈python3中用for循环删除列表中元素的坑
2018/04/19 Python
TensorFlow利用saver保存和提取参数的实例
2018/07/26 Python
Python爬虫 scrapy框架爬取某招聘网存入mongodb解析
2019/07/31 Python
python GUI库图形界面开发之PyQt5切换按钮控件QPushButton详细使用方法与实例
2020/02/28 Python
解决flask接口返回的内容中文乱码的问题
2020/04/03 Python
美国顶级防滑鞋:Shoes For Crews
2017/03/27 全球购物
英国户外服装、鞋类和设备的领先零售商:Millets
2020/10/12 全球购物
递归实现回文判断(如:abcdedbca就是回文,判断一个面试者对递归理解的简单程序)
2013/04/28 面试题
2014三八妇女节活动总结
2014/03/01 职场文书
小学学校门卫岗位职责
2014/08/03 职场文书
医院反腐倡廉演讲稿
2014/09/16 职场文书
2015年乡镇安全生产工作总结
2015/05/19 职场文书
2016年安全生产先进个人事迹材料
2016/02/29 职场文书
掌握这项技巧,一年阅读300本书不是梦
2019/09/12 职场文书
Pytorch反向传播中的细节-计算梯度时的默认累加操作
2021/06/05 Python
Spring Boot项目传参校验的最佳实践指南
2022/04/05 Java/Android