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使用者可以根據版本的不同酌情進行相應的調整。