search
Homephp教程php手册PHPLIB 和多个数据库连接

数据|数据库|数据库连接

你可能有一个站点,有些页面要处理数据库。你可能想使用PHPLIB,但是不想为了适应它而改变现存的数据库。这儿给出实现你的梦想的答案。PHPLIB和多个数据库。

实现它需要对PHPLIB进行扩充。本文解释了如何创建扩充。你会发现,这篇文章会帮助你在其它方面对PHPLIB进行扩充。阅读完这篇文章后,思考一下PHPLIB可以完成你想要的98%的情况吧。

这篇文章所提及的PHPLIB的扩充的建议已经提交给了PHPLIB的开发组。因此,在未来的版本中,可能会出现这些扩充。在你的网页中的其它的代码将帮助你组织你的数据库管理。

数据库管理

你可以将每一个表放在一个巨大的数据库中。然而,总有一天会刺伤你。对数据库进行管理将会使创伤减小到最小。当你的数据库对一个服务器来说太大时会出现什么情况?当一个服务器不能处理IO吞吐量或者没有足够的内存进行处理又会怎么样?将现有的数据库进行拆分很难,但是从分离的数据库开始则容易多了,并且好的数据库管理会很有帮助。

如果你经营一家书店,你可能有作者列表,带有价格的书目列表,当前库存列表和订单列表。随着你的业务的发展,订单列表会增加,并且每一个订单会占用很多的磁盘空间。一种可能性就是有一天你会将订单直接放进财务系统。

现在开始将订单放在分离的数据库中。因为库存的数量是随着订单而变化的,所以将库存数据放在同一个数据库中。

作者列表和书目列表为一些静态信息,它们会经常被读到,但是很少改变。实际上,唯一的改变可能就是对于作者记录会每5年一次,这可能是当这个作者写了一本新书(或死亡了)。这些数据可能使用与订单数据库完全不同的配置。

包含PHPLIB

PHPLIB通过一个名为DB_Sql的类来操作SQL数据库。在你的代码中包含适合你的数据库的版本。在这个例子中,我使用MySQL版本。

为了在你的代码中得到DB_Sql,在PHPLIB要求的目录下安装PHPLIB文件。然后,找到你的cgi-bin目录,然后在cgi-bin目录下创建phplib目录。接着,拷贝所有的PHPLIB中的.inc文件到phplib目录下。最后,将phplib目录放在php.ini文件中include_path = 的那行上。

include_path是PHP引用在include()或require()中文件名的地方。在我的NT工作站上,包含路径是

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

在Linux机器上,则为

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

在每一个PHP页面的顶端为




require(common.php3);



?>



common.php3在包含目录中,包含对每一页都通用的所有的数据和函数。在common.php3中,为


require(db_mysql.inc);

require(ct_sql.inc);

require(session.inc);

require(auth.inc);

require(perm.inc);

require(user.inc);

require(page.inc);



?>



阅读PHPLIB文档(http://phplib.netuse.de),也可以在http://www.phpbuilder.com下查找一些好文章,来了解你需要包括些什么。Db_mysql.inc包含了DB_Sql类的定义。如果你想将MySQL改换成PostGreSQL数据库,将db_mysql.inc改成对db_pgsql.inc的包含。那里有10个.inc文件,涵盖了MS SQL,Oracle,Sybase和其它一些数据库。

请注意,在这个例子中,require()和include()是完全一样的。Require()和include()工作方式不同,当用在代码中间或在if()语句中时,结果是不一样的。

扩充PHPLIB

PHPLIB处理数据库是通过从DB_Sql类创建的一个对象实现的。Db_mysql.inc包含了DB_Sql类,为MySQL 进行了修改。我们将通过向common.php3添加代码来扩充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中找到connnect()函数(或针对你的数据库的.inc文件),然后将其拷贝到common.php3中,在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和数据库名称。因此,使这两个变量对PHPLIB外部可见。在common.php3:


$db_connection = 0; // 普通数据库连接id

$db_database = ""; // 当前数据库名字

?>


接着,我们修改PHPLIB来保存连接id和数据库名字在这些字段中。你的其它的代码可以设置和使用同一字段。如果你需要在诊断问题时知道哪一个数据库正在使用,在你的页面中插入这些代码:


Print("
db_database: " . $db_database . "

");

?>

(有一些更简洁的方法来书写打印语句。这个方法可以在彩色代码编辑器中加亮变量名。这个方法对于数组和其它复合变量名工作也很稳定。)

我们如何让connect()来使用新的变量呢?我们可在项部加入额外的行,所以你可以:


{

globals $db_connect, $db_database;

/* 缺省处理 */



?>

这行使我们的外部变量在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);

}



?>


通过定义这些通用函数一次,你可以在各种地方得到通用变量,不需要在所有地方增加全局行。这儿就是使用了我们的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之外,这样在代码中需要进行数据库选择的地方我们可以使用相同的函数。



  在这种情况下只有一个不好的地方:我们假设相同的主机,用户和口令,用于所有的数据库操作。如果你使用一个用户登录,使用特别的权限处理指定的数据库,你将不得不为这种处理创建一个特别的连接。怎么办呢?定义变量:






$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.php3中时,我们需要派生DB_Sql类。我们通过封装connect()来实现:






class db_DB_Sql extends DB_Sql {



}



?>



  可以查阅PHP的文档关于对象和类的内容,看一下"extends"做了些什么。用最少的话来说就是:在派生中定义的每个东西替换或覆盖了原始定义的东西。



  现在可以使用db_DB_Sql了。当你安装好PHPLIB时,你会有一条语句,写为:






$x = new DB_Sql;



?>



  将其改成:






$x = new db_DB_Sql;



?>



  这样就会使用修改后的类,代替了原始的类。



  你现在已经成了一个对象,类,OOP的专家了,可以要求每年薪水为,100了。(老外胆子够大)



  我们做了一个有效的修改,而且对PHPLIB代码的影响最小。记录下修改的痕迹,这样你可以将其重用于PHPLIB的新版本中。如果在数据库处理中出现错误,你可以在外部的函数中插入print语句,看一看在连接时发生了什么。现在你可以做更多的事情了,而没有修改PHPLIB代码。



  如果SQL看上去失败了,你可以将qurey()函数从db_mysql.inc中的DB_Sql中拷贝到common.PHP3中的db_DB_Sql中去,然后插入print语句,查看SQL的使用情况。



  PHPLIB会记录cookie。在PHPLIB中间的一条print语句可能会产生错误消息,是关于输出HTTP头信息的问题。可以忽略错误,或者将诊断信息写到一个磁盘文件中去。



  开始为:



$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."rn");

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()。你也可以替换:


db_database("bookcatalogue");

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



?>




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

db_connect());



?>

建议做成函数:



function db_query($db_query_database, $db_query_sql) {

return(mysql_db_query(db_database($db_query_database), $db_query_sql,

db_connect());

}



?>

现在你可以实现

使用PHPLIB(和任何相似的软件)处理多个数据库

扩充类/对象

插入诊断检查

将日志信息写入文件中

以相反的次序实践它们。在日志文件可工作后,然后是诊断检查,然后是对类的扩充,然后是多个数据库。



Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
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数据库错误需要从多个方面入手,逐步排查问题原因,并采取相应的措施进行修复。

Leak reveals key specs of Intel Arrow Lake-U, -H, -HX and -SLeak reveals key specs of Intel Arrow Lake-U, -H, -HX and -SJun 15, 2024 pm 09:49 PM

IntelArrowLakeisexpectedtobebasedonthesameprocessorarchitectureasLunarLake,meaningthatIntel'sbrandnewLionCoveperformancecoreswillbecombinedwiththeeconomicalSkymontefficiencycores.WhileLunarLakeisonlyavailableasava

Oracle和DB2数据库技术对比解析Oracle和DB2数据库技术对比解析Mar 11, 2024 am 09:54 AM

Oracle和DB2是两个知名的关系型数据库管理系统(RDBMS),在企业级应用中被广泛使用。在本文中,我们将对Oracle和DB2这两种数据库技术进行比较并进行详细解析,包括其特点、性能、功能和使用示例等方面的分析。一、Oracle数据库技术概述Oracle是由美国甲骨文公司开发的一种关系型数据库管理系统。它被广泛应用于企业级应用中,具有强大的性能、稳定性

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 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文件并不是特定的文件格式。

Oracle和DB2数据库管理系统的特点对比Oracle和DB2数据库管理系统的特点对比Mar 11, 2024 am 08:57 AM

Oracle和DB2是两种常见的关系型数据库管理系统,它们都有各自独特的特点和优势。本文将对Oracle和DB2进行特点对比,并提供具体的代码示例来说明它们之间的差异。一、Oracle数据库管理系统的特点:存储引擎:Oracle数据库使用了自己独有的存储引擎,称为Oracle数据库引擎(OracleDatabaseEngine),它能够处理大规模的数据存

db是什么文件格式db是什么文件格式Mar 07, 2023 pm 05:27 PM

db是数据库文件格式,是软件用来存储数据的文件,它等效于数据库。每个软件都有其自己的存储格式,即数据的排列方式;一些软件数据文件的后缀是DB。例如Win7系统下的Thumbs.db是缩略图数据文件;因此,db文件不是特定的文件格式。

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

Repo: How To Revive Teammates
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: How To Get Giant Seeds
1 months agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.

Atom editor mac version download

Atom editor mac version download

The most popular open source editor

mPDF

mPDF

mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.