首頁 php教程 php手册 PHPLIB访问多个数据库

PHPLIB访问多个数据库

Jun 21, 2016 am 09:07 AM
connect database db this

访问|数据|数据库

【摘 要】 如果你要使用多个数据库的话,它就显得力不从心了,本文介绍了通过扩展PHPLIB,让你鱼和熊掌兼得,在使用PHPLIB的同时可以使用多个数据库,而且从中你也可以了解到面向对象编程和如何扩展库的知识。
  PHPLIB是PHP的一些扩展库,使用它我们可以很方便地对数据库进行各种操作,不过,如果你要使用多个数据库的话,它就显得力不从心了,本文介绍了通过扩展PHPLIB,让你鱼和熊掌兼得,在使用PHPLIB的同时可以使用多个数据库,而且从中你也可以了解到面向对象编程和如何扩展库的知识,值得一读。

数据库管理

   你可以在一个大型的数据库中放入任何表。不过时间长了,将会令数据库变得越来越大,服务器可能会跟不上IO的工作,或者没有足够的内存应付所有的访问?要分开现有的数据又非常难。明智的办法是开始时就使用分开的数据库,并且进行有效的数据库管理。 如果你有一个卖书的网站,你可能有作者的列表,书价的列表,还有当前的库存和订单的列表。当你的业务不断增长时,订单将会不断地增长,而且处理每个订单都需要进行很多的磁盘访问。很可能你将在某一天将所有的订单都放到一个会计系统中。

  现在就将订单放到一个独立的数据库吧。由于库存也是通过订单更新的,因此库存量也放到同样的数据库中。

  作者的列表和书的列表都是一些静态的信息,要经常读取,但很少更新。实际上,更新一个作者的记录可能只需要每5年一次,只在作者写了一本新书(或者去世)时进行。放这些数据的服务器的配置可与放订单数据库的服务器完全不同。

包含PHPLIB

  PHPLIB通过一个称为DB_Sql的类访问SQL数据库。根据你需要使用的数据库类型,将不同的inc文件包含在你的代码中。在这个例子中,我使用MySQL的版本。

  为了在你的代码中使用DB_Sql,要将PHPLIB文件安装在它们自己的目录中。然后,找到你的cgi-bin目录,并且在cgi-bin的目录旁创建phplib目录。下一步,拷贝所有的PHPLIB .inc文件到phplib目录。最后,修改php.inc文件,只要将“include_path=”的行改为该phplib目录就可以了。

include_path是PHP使用include()或者require()时查找的目录,在我的NT workstation中,include的路径是:

include_path = ".;i:/project52/includes;i:/project52/phplib";

在Linux的系统上

include_path = ".;/home/httpd/includes;/home/httpd/phplib";

在每个PHP页面的顶部加入

require(common.php);

?>
common.php3放在includes目录中,包含了每个页面要用到的所有数据和函数。在这个例子中的common.php是:

require(db_mysql.inc);
require(ct_sql.inc);
require(session.inc);
require(auth.inc);
require(perm.inc);
require(user.inc);
require(page.inc);

?>

  如果你想知道每个inc文件的用处,可阅读http://phplib.netuse.de上的PHPLIB文档。Db_mysql.inc包含了所有DB_SQL类的定义。如果你想使用PostGreSQL代替MySQL,只要用db_pgsql.inc代替db_mysql.inc就可以了。还有10个其它的.inc文件,可以使用MS SQL、Oracle、Sybase或者其它的数据库。

  要注意的是,在这个例子中,require()和include()是完全一样的。不过,如果放在代码中,或者在if语句中使用时,Require()和include的使用是完全不同的,并且有不同的运行结果。

扩展PHPLIB

  PHPLIB通过一个DB_Sql类产生的对象来访问数据库。Db_mysql.inc包含了为MySQL修改过的DB_Sql类。我们将通过在common.php中加入代码来扩展DB_sql,这些代码将加在包含db_mysql.inc的行后。

DB_Sql包含了很多用作查询的函数,我们要作修改的是:

/* public: 连接管理 */
function connect($Database = "", $Host = "", $User = "", $Password = "") {
/* 处理默认连接 */
if ("" == $Database)
$Database = $this->Database;
if ("" == $Host)
$Host = $this->Host;
if ("" == $User)
$User = $this->User;
if ("" == $Password)
$Password = $this->Password;

/* 建立连接,选择数据库 */

if ( 0 == $this->Link_ID ) {
$this->Link_ID=mysql_pconnect($Host, $User, $Password);
if (!$this->Link_ID) {
$this->halt("pconnect($Host, $User, \$Password) failed.");
return 0;
}

if (!@mysql_select_db($Database,$this->Link_ID)) {
$this->halt("cannot use database ".$this->Database);
return 0;
}
}

return $this->Link_ID;
}

?>

  在你的db_mysql.inc(或者其它数据库的相关.inc文件)中找到connect()函数,然后将它拷贝到common.php,放到包含db_mysql.inc代码的后面,在后面,还要将它封装为一个类的定义。

我发现这些代码有些难读,因此,首先令拷贝来的代码的可读性更好:

/* public: 连接管理*/

function connect($Database = "", $Host = "", $User = "", $Password = "") {
/* 处理默认连接 */
if ("" == $Database) {
$Database = $this->Database;
}
if ("" == $Host) {
$Host = $this->Host;
}
if ("" == $User) {
$User = $this->User;
}
if ("" == $Password) {
$Password = $this->Password;
}
/* 建立连接,选择数据库 */
if ( 0 == $this->Link_ID ) {
$this->Link_ID=mysql_pconnect($Host, $User, $Password);
if (!$this->Link_ID) {
$this->halt("pconnect($Host, $User, \$Password) failed.");
return 0;
}
if (!@mysql_select_db($Database,$this->Link_ID)) {
$this->halt("cannot use database ".$this->Database);
return 0;
}
}
return $this->Link_ID;
}

?>

  我调整了一下括号的位置,并且在单行的前后也加入了一个大括号。在PHP的if语句中,如果只有一句代码的话你可以不用括号,但是,如果你增加多一行代码,就会马上出错。因此我建议你加入一个括号,以免后来加入代码时出错。

  在改变connect的代码之前,先要了解一下connect()是如何工作的,它检查当前是否存在一个连接,如果不存在连接的话,就创建一个连接。在每次的数据库查询之前,首先运行这个connect()函数。可惜的是,它只在首次连接的时候选择数据库,如果你的PHP页面使用超过一个数据库,connect()并不会选择另外的数据库。

  要改变代码的话,有几种不同的方法。我们要选择一种对PHPLIB的影响最小,而且可让我们在需要分析问题的时候,能够显示数据库连接状态的方法。我们需要在PHPLIB外保存连接id和数据库的名字。只要在common.php加入:

$db_connection = 0; // 数据库连接的id
$db_database = ""; // 当前数据库的状态

?>

  下一步,我们要对PHPLIB作修改,以便在这些变量中存储连接id和数据库的名字。在其它的代码中,你可以设置和使用同样的变量名。在分析问题时,如果你需要知道现在使用哪个数据库,只要在页面中插入以下的代码:

Print("

db_database: " . $db_database . "

");

?>

我们怎样才能让connect()使用这些新变量呢?我们可以在顶部加入一行:

{
globals $db_connect, $db_database;
/* Handle defaults */

?>

通过这些代码,新变量就可被connect()访问到

在定义了$db_database后,加入:

function db_connect($db_connect_host="", $db_connect_user="",$db_connect_pass="") {
globals $db_connect;
if(!empty($db_connect_host)) {
$db_connect = mysql_pconnect($db_connect_host,
$db_connect_user, $db_connect_pass);
}
return($db_connect);
}

function db_database($db_database_new="") {
globals $db_database;
if(!empty($db_database_new)) {
$db_database = @mysql_select_db($db_database_new, db_connect());
}
return($db_database);
}

?>

  只要定义这些公共的函数一次,你就可以在不同的地方使用这些公共的变量,而不需要加入global申明。以下就是使用上面db函数的公共函数:

function connect($Database = "", $Host = "", $User = "", $Password = "") {
/* 处理默认连接 */
if ("" == $Database) {
$Database = $this->Database;
}
if ("" == $Host) {
$Host = $this->Host;
}
if ("" == $User) {
$User = $this->User;
}
if ("" == $Password) {
$Password = $this->Password;
}
/* 建立连接,选择数据库 */
if ( 0 == db_connect()) {
$this->Link_ID = db_connect($Host, $User, $Password);
if (!$this->Link_ID) {
$this->halt("pconnect($Host, $User, \$Password) failed.");
return 0;
}
}
if (0 != db_connect()) {
if($Database != db_database()) {
$this->Database = db_database($Database))
if(empty($this->Database)) {
$this->halt("cannot use database " . $this->Database);
return 0;
}
}
}
return $this->Link_ID;
}

?>

留意以下改变:

  对数据库的测试从连接的测试中分离出来,这样即使connect()有一个当前连接时,还可以检查是否要换成另外的数据库。这意味着与以前相比,db_connect()和0作比较的次数多了一倍,不过这个额外的处理是必要的。

  我们将数据库连接和数据库选择放在PHPLIB外,这样你就可以在PHP代码的任何地方使用同样的数据库选择函数。

  不过,现在的处理有一个限制,这里我们是假定对于所有的数据库,都使用同样的主机、用户和密码。如果你的数据库对于不同的用户有不同的权限,你必须建立一个特别的连接来访问它。怎样做?只要定义以下变量就可以了:

$db_host = "";
$db_user = "";
$db_pass = "";

?>

  通过扩展db_database()函数,将当前的用户和主机和某个用户和主机作对比就行。你还可以加入:

$db_type = "";

?>

  这个变量用来存储数据库的类型,mysql或者Oracle等。这样你就可以访问多个数据库。

  不过要改变代码来处理多个不同类型的数据库是颇复杂的。你必须还要改变查询函数,以及连接和选择函数。你或许可通过PHP的ODBC来连接,然后使用PHPLIB的ODBC选项来处理。ODBC通过一个通用的方式来处理多种数据库,因此将会慢一点。ODBC虽然可让你使用同样的代码来处理多个不同类型的数据库。但是在需要用到不同处理格式的日期时,将会有问题,而且在数据库间也会存在一些奇怪的差异。ODBC只是简化了连接,但是并没有修改数据库解释数据和SQL的方式。

  现在来学习一下如何重新定义一个对象类。connect()函数被封装到一个类的定义中:

class DB_Sql {

}

?>

我们将该函数拷贝到common.php时,我们必须重新定义DB_Sql类,我们可以这样封装connect():

class db_DB_Sql extends DB_Sql {

}

?>

  要详细了解"extends"的工作,我们可以看看PHP文档中关于对象和类的部分。简单说来:扩展部分的任何定义替换和覆盖了以前的所有定义。

现在可以使用db_DB_Sql。在你配置PHPLIB时,你要做以下声明:

$x = new DB_Sql;

?> Change it to:

$x = new db_DB_Sql;

?>

这样你就可以使用修改的类,而不是以前的类。

  在连接数据库出错的时候,你可以在外部的函数中输出目前的连接状态。如果SQL语句出错,你也可以将DB_Sql中的query()函数拷贝到common.PHP的db_DB_Sql中,然后插入一个输出语句,看看当前的SQL语句是什么。

你也可以将错误或者诊断的信息写到一个磁盘文件中。通过定义

$db_log_file = "t:/diag.txt";

或者一个类似的文本文件。如果使用Windows,你要确保该目录存在,否则你会得到一个错误的信息。

然后定义一个函数:

function db_log($db_log_message) {
globals $db_log_file;
$db_log_f = fopen($db_log_file, "a");
fwrite($db_log_f, date("Y m d H:i:s")." ".$db_log_message."\r\n");
fclose($db_log_f);
}

?>

在你需要记录信息的地方,加入以下代码:

db_log("current database: " . db_database());

?>

  其实你可以使用内置的或者系统的日志文件。不过这样你就要在一大堆的文件中查找一小段信息。因此这个独立的记录文件可帮助你进行测试。我建议在记录前后写以下的代码:

db_log("current database: " . db_database());
db_database("bookcatalogue");
db_log("current database: " . db_database());

?>

  在数据访问时,要记得使用正确的数据库,而不是PHPLIB中定义的数据库。你可以为该数据库创建一个封装的函数,或者改变你使用的函数。如果你使用mysql_query(),你可以先用db_database(),你可以用

$result = mysql_db_query(db_database("bookcatalogue"), "select * from?",
db_connect());

?> which suggests the function:

function db_query($db_query_database, $db_query_sql) {
return(mysql_db_query(db_database($db_query_database), $db_query_sql,
db_connect());
}

?>

来代替

db_database("bookcatalogue");
$result = mysql_query("select * from?", db_connect());

?>

现在你可以做到

.使用PHPLIB(或者类似的软件)来访问多个数据库
.扩展类/对象
.插入诊断检查
.建立日志文件

  通过这篇文章,相信对于如何扩展一个类,你也有了一些概念,自己实践一下吧。



本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1664
14
CakePHP 教程
1423
52
Laravel 教程
1321
25
PHP教程
1269
29
C# 教程
1249
24
discuz database error怎麼解決 discuz database error怎麼解決 Nov 20, 2023 am 10:10 AM

discuz database error的解決方法有:1、檢查資料庫配置;2、確保資料庫伺服器正在運作;3、檢查資料庫表狀態;4、備份資料;5、清理快取;6、重新安裝Discuz;7、檢查伺服器資源;8、聯繫Discuz官方支持。解決Discuz資料庫錯誤需要從多個方面入手,逐步排除問題原因,並採取相應的措施進行修復。

洩漏揭示了英特爾 Arrow Lake-U、-H、-HX 和 -S 的關鍵規格 洩漏揭示了英特爾 Arrow Lake-U、-H、-HX 和 -S 的關鍵規格 Jun 15, 2024 pm 09:49 PM

英特爾ArrowLake預計將基於與LunarLake相同的處理器架構,這意味著英特爾全新的LionCove效能核心將與經濟體的Skymont效率核心結合。

Oracle與DB2的SQL語法比較與區別 Oracle與DB2的SQL語法比較與區別 Mar 11, 2024 pm 12:09 PM

Oracle和DB2是兩個常用的關聯式資料庫管理系統,它們都有自己獨特的SQL語法和特性。本文將針對Oracle和DB2的SQL語法進行比較與區別,並提供具體的程式碼範例。資料庫連接在Oracle中,使用以下語句連接資料庫:CONNECTusername/password@database而在DB2中,連接資料庫的語句如下:CONNECTTOdataba

Oracle與DB2資料庫技術比較解析 Oracle與DB2資料庫技術比較解析 Mar 11, 2024 am 09:54 AM

Oracle和DB2是兩個知名的關聯式資料庫管理系統(RDBMS),在企業級應用中廣泛使用。在本文中,我們將對Oracle和DB2這兩種資料庫技術進行比較並進行詳細解析,包括其特點、效能、功能和使用範例等方面的分析。一、Oracle資料庫技術概述Oracle是由美國甲骨文公司開發的關係型資料庫管理系統。它被廣泛應用於企業級應用中,具有強大的性能、穩定性

Oracle和DB2資料庫效能比較分析 Oracle和DB2資料庫效能比較分析 Mar 09, 2024 pm 10:00 PM

Oracle和DB2資料庫是兩個領先的關係型資料庫管理系統,它們在企業級應用程式中廣泛使用。在實際應用中,資料庫的效能往往是評估資料庫系統優劣的重要指標之一。本文將對Oracle和DB2資料庫的效能進行比較分析,並結合具體的程式碼範例來展示它們之間的差異。一、Oracle資料庫效能分析Oracle資料庫是一款功能強大的資料庫管理系統,具有良好的可擴展性和穩定性

db是什麼文件格式? db是什麼文件格式? May 19, 2021 am 11:56 AM

db是「datebase」的縮寫,是「資料庫檔案」的一種格式,是軟體用來存放資料的一個文件,相當於資料庫,每種軟體都有它自己的存放格式。例如Win7系統下的「Thumbs.db」就是縮圖資料文件,所以db檔案並不是特定的檔案格式。

db是什麼檔案格式 db是什麼檔案格式 Mar 07, 2023 pm 05:27 PM

db是資料庫檔案格式,是軟體用來儲存資料的文件,它等效於資料庫。每個軟體都有自己的儲存格式,即資料的排列方式;有些軟體資料檔案的後綴是DB。例如Win7系統下的Thumbs.db是縮圖資料檔;因此,db檔不是特定的檔案格式。

Oracle和DB2資料庫管理系統的特性對比 Oracle和DB2資料庫管理系統的特性對比 Mar 11, 2024 am 08:57 AM

Oracle和DB2是兩種常見的關聯式資料庫管理系統,它們都有各自獨特的特色和優勢。本文將對Oracle和DB2進行特點對比,並提供具體的程式碼範例來說明它們之間的差異。一、Oracle資料庫管理系統的特性:儲存引擎:Oracle資料庫使用了獨有的儲存引擎,稱為Oracle資料庫引擎(OracleDatabaseEngine),它能夠處理大規模的資料存

See all articles