程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> 使用PHPLIB訪問多個數據庫

使用PHPLIB訪問多個數據庫

編輯:關於PHP編程

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頁面的頂部加入
<?php
require(common.php);
?>
common.php3放在includes目錄中,包含了每個頁面要用到的所有數據和函數。在這個例子中的common.php是:
<?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包含了很多用作查詢的函數,我們要作修改的是:

<?php
/* 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 (Link_ID">!@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代碼的後面,在後面,還要將它封裝為一個類的定義。

我發現這些代碼有些難讀,因此,首先令拷貝來的代碼的可讀性更好:

<?php
/* 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 (Link_ID">!@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加入:

<?php
$db_connection = 0; // 數據庫連接的id
$db_database = ""; // 當前數據庫的狀態
?>

  下一步,我們要對PHPLIB作修改,以便在這些變量中存儲連接id和數據庫的名字。在其它的代碼中,你可以設置和使用同樣的變量名。在分析問題時,如果你需要知道現在使用哪個數據庫,只要在頁面中插入以下的代碼:

<?php
Print(" db_database: " . $db_database . "");
?>

我們怎樣才能讓connect()使用這些新變量呢?我們可以在頂部加入一行:

<?php
{
globals $db_connect, $db_database;
/* Handle defaults */
?>

通過這些代碼,新變量就可被connect()訪問到

在定義了$db_database後,加入:
<?php
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函數的公共函數:

<?php
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作比較的次數多了一倍,

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved