电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

使用PHPLIB訪問多個數據庫

瀏覽:111日期:2024-01-09 17:04:02

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頁面的頂部加入<?phprequire(common.php);?>common.php3放在includes目錄中,包含了每個頁面要用到的所有數據和函數。在這個例子中的common.php是:<?phprequire(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 (!@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 (!@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和數據庫的名字。在其它的代碼中,你可以設置和使用同樣的變量名。在分析問題時,如果你需要知道現在使用哪個數據庫,只要在頁面中插入以下的代碼:

<?phpPrint(' db_database: ' . $db_database . '');?>

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

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

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

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

<?phpfunction 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代碼的任何地方使用同樣的數據庫選擇函數。不過,現在的處理有一個限制,這里我們是假定對于所有的數據庫,都使用同樣的主機、用戶和密碼。如果你的數據庫對于不同的用戶有不同的權限,你必須建立一個特別的連接來訪問它。怎樣做?只要定義以下變量就可以了:

<?php$db_host = '';$db_user = '';$db_pass = '';?>

通過擴展db_database()函數,將當前的用戶和主機和某個用戶和主機作對比就行。你還可以加入:

<?php$db_type = '';?>

這個變量用來存儲數據庫的類型,mysql或者Oracle等。這樣你就可以訪問多個數據庫。

不過要改變代碼來處理多個不同類型的數據庫是頗復雜的。你必須還要改變查詢函數,以及連接和選擇函數。你或許可通過PHP的ODBC來連接,然后使用PHPLIB的ODBC選項來處理。ODBC通過一個通用的方式來處理多種數據庫,因此將會慢一點。ODBC雖然可讓你使用同樣的代碼來處理多個不同類型的數據庫。但是在需要用到不同處理格式的日期時,將會有問題,而且在數據庫間也會存在一些奇怪的差異。ODBC只是簡化了連接,但是并沒有修改數據庫解釋數據和SQL的方式。

現在來學習一下如何重新定義一個對象類。connect()函數被封裝到一個類的定義中:<?phpclass DB_Sql {}?>

我們將該函數拷貝到common.php時,我們必須重新定義DB_Sql類,我們可以這樣封裝connect():<?phpclass db_DB_Sql extends DB_Sql {}?>

要詳細了解'extends'的工作,我們可以看看PHP文檔中關于對象和類的部分。簡單說來:擴展部分的任何定義替換和覆蓋了以前的所有定義。

現在可以使用db_DB_Sql。在你配置PHPLIB時,你要做以下聲明:

<?php$x = new DB_Sql;?> Change it to: <?php$x = new db_DB_Sql;?>

這樣你就可以使用修改的類,而不是以前的類。

在連接數據庫出錯的時候,你可以在外部的函數中輸出目前的連接狀態。如果SQL語句出錯,你也可以將DB_Sql中的query()函數拷貝到common.PHP的db_DB_Sql中,然后插入一個輸出語句,看看當前的SQL語句是什么。

你也可以將錯誤或者診斷的信息寫到一個磁盤文件中。通過定義

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

或者一個類似的文本文件。如果使用Windows,你要確保該目錄存在,否則你會得到一個錯誤的信息。

然后定義一個函數:

<?phpfunction 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.'rn');fclose($db_log_f);}?>

在你需要記錄信息的地方,加入以下代碼:

<?phpdb_log('current database: ' . db_database());?>

其實你可以使用內置的或者系統的日志文件。不過這樣你就要在一大堆的文件中查找一小段信息。因此這個獨立的記錄文件可幫助你進行測試。我建議在記錄前后寫以下的代碼:

<?phpdb_log('current database: ' . db_database());db_database('bookcatalogue');db_log('current database: ' . db_database());?>

在數據訪問時,要記得使用正確的數據庫,而不是PHPLIB中定義的數據庫。你可以為該數據庫創建一個封裝的函數,或者改變你使用的函數。如果你使用mysql_query(),你可以先用db_database(),你可以用

<?php$result = mysql_db_query(db_database('bookcatalogue'), 'select * from?',db_connect());?> which suggests the function: <?phpfunction db_query($db_query_database, $db_query_sql) {return(mysql_db_query(db_database($db_query_database), $db_query_sql,db_connect());}?>

來代替

<?phpdb_database('bookcatalogue');$result = mysql_query('select * from?', db_connect());?>

現在你可以做到

.使用PHPLIB(或者類似的軟件)來訪問多個數據庫.擴展類/對象.插入診斷檢查.建立日志文件

標簽: PHP
主站蜘蛛池模板: 交通信号灯生产厂家_红绿灯厂家_电子警察监控杆_标志杆厂家-沃霖电子科技 | 炒货机-炒菜机-炒酱机-炒米机@霍氏机械 | 北京森语科技有限公司-模型制作专家-展览展示-沙盘模型设计制作-多媒体模型软硬件开发-三维地理信息交互沙盘 | 辽宁资质代办_辽宁建筑资质办理_辽宁建筑资质延期升级_辽宁中杭资质代办 | 免费网站网址收录网_海企优网站推荐平台 | 塑钢课桌椅、学生课桌椅、课桌椅厂家-学仕教育设备首页 | 北京租车公司_汽车/客车/班车/大巴车租赁_商务会议/展会用车/旅游大巴出租_北京桐顺创业租车公司 | 安徽合肥格力空调专卖店_格力中央空调_格力空调总经销公司代理-皖格制冷设备 | 生产加气砖设备厂家很多,杜甫机械加气砖设备价格公道 | 电脑知识|软件|系统|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网 | 热工多功能信号校验仪-热电阻热电偶校验仿真仪-金湖虹润仪表 | 断桥铝破碎机_铝合金破碎机_废铁金属破碎机-河南鑫世昌机械制造有限公司 | 【铜排折弯机,钢丝折弯成型机,汽车发泡钢丝折弯机,线材折弯机厂家,线材成型机,铁线折弯机】贝朗折弯机厂家_东莞市贝朗自动化设备有限公司 | 淬火设备-钎焊机-熔炼炉-中频炉-锻造炉-感应加热电源-退火机-热处理设备-优造节能 | Akribis直线电机_直线模组_力矩电机_直线电机平台|雅科贝思Akribis-杭州摩森机电科技有限公司 | 工业废水处理|污水处理厂|废水治理设备工程技术公司-苏州瑞美迪 今日娱乐圈——影视剧集_八卦娱乐_明星八卦_最新娱乐八卦新闻 | 一体化污水处理设备_生活污水处理设备_全自动加药装置厂家-明基环保 | 反渗透水处理设备|工业零排放|水厂设备|软化水设备|海南净水设备--海南水处理设备厂家 | 深圳善跑体育产业集团有限公司_塑胶跑道_人造草坪_运动木地板 | 清水-铝合金-建筑模板厂家-木模板价格-铝模板生产「五棵松」品牌 | 沥青车辙成型机-车托式混凝土取芯机-混凝土塑料试模|鑫高仪器 | 胶原检测试剂盒,弹性蛋白检测试剂盒,类克ELISA试剂盒,阿达木单抗ELISA试剂盒-北京群晓科苑生物技术有限公司 | 金库门,金库房,金库门厂家,金库门价格-河北特旺柜业有限公司 | 聚丙烯酰胺PAM-聚合氯化铝PAC-絮凝剂-河南博旭环保科技有限公司 巨野电机维修-水泵维修-巨野县飞宇机电维修有限公司 | 管理会计网-PCMA初级管理会计,中级管理会计考试网站 | 广州监控安装公司_远程监控_安防弱电工程_无线wifi覆盖_泉威安防科技 | 全自动贴标机-套标机-工业热风机-不干胶贴标机-上海厚冉机械 | 云南标线|昆明划线|道路标线|交通标线-就选云南云路施工公司-云南云路科技有限公司 | 磨煤机配件-高铬辊套-高铬衬板-立磨辊套-盐山县宏润电力设备有限公司 | 室内室外厚型|超薄型|非膨胀型钢结构防火涂料_隧道专用防火涂料厂家|电话|价格|批发|施工 | 圣才学习网-考研考证学习平台,提供万种考研考证电子书、题库、视频课程等考试资料 | 重庆网站建设,重庆网站设计,重庆网站制作,重庆seo,重庆做网站,重庆seo,重庆公众号运营,重庆小程序开发 | 真空包装机-诸城市坤泰食品机械有限公司| 环保袋,无纺布袋,无纺布打孔袋,保温袋,环保袋定制,环保袋厂家,环雅包装-十七年环保袋定制厂家 | 上海办公室设计_办公楼,写字楼装修_办公室装修公司-匠御设计 | 网站建设-网站制作-网站设计-网站开发定制公司-网站SEO优化推广-咏熠软件 | 薪动-人力资源公司-灵活用工薪资代发-费用结算-残保金优化-北京秒付科技有限公司 | 硅胶管挤出机厂家_硅胶挤出机生产线_硅胶条挤出机_臣泽智能装备 贵州科比特-防雷公司厂家提供贵州防雷工程,防雷检测,防雷接地,防雷设备价格,防雷产品报价服务-贵州防雷检测公司 | 阿里巴巴诚信通温州、台州、宁波、嘉兴授权渠道商-浙江联欣科技提供阿里会员办理 | 篷房|仓储篷房|铝合金篷房|体育篷房|篷房厂家-华烨建筑科技官网 知名电动蝶阀,电动球阀,气动蝶阀,气动球阀生产厂家|价格透明-【固菲阀门官网】 | 成都治疗尖锐湿疣比较好的医院-成都治疗尖锐湿疣那家医院好-成都西南皮肤病医院 |