PEAR:创建中间的数据库应用层1
创建|数据|数据库
内容:
一、 什么是DB类
二、 为什么要设计抽象的中间数据层
三、 DB的使用入门
四、 DB_Common 使用参考
五、 更进一步,创建你自己的中间数据库应用层
六、 DB的不足
七、参考资源
关于作者
相关内容:
1、用PEAR来写你的下一个php程序
2、常用模块
3、使用PHPDoc轻松建立你的PEAR文档
潘凡 (nightsailer@hotmail.com)
北京赛迪网信息技术有限公司
2001 年 8 月
对于PHP的应用程序来说,90%以上需要和数据库来打交道。那么,你是如何操纵数据库的?当你的后端数据库升级或变迁后,你的这些程序是否能够随之平滑地升级和挂接呢?如果你正在考虑这个问题,那么不妨和我来讨论一下,如何使用PEAR中的DB类来创建与数据库无关的数据库应用层。
一、 什么是DB类
我们首先简单地了解一下DB类。DB类是PEAR中进行数据操作的几个类的集合,它的主要目的是提供一个统一的,抽象的数据接口,这个接口与后端的数据库是无关的。因此,如果你的应用程序使用这个通用的接口来进行数据库的操作,那么就能够平滑地切换到不同的数据库下面,如MYSQL,SQL,SYBASE等等。实际上,DB类希望能够起到简单的类似ODBC或者是PERL中的DBI的作用。说到这里,不得不提一下PHP中的另一个优秀的库:ADODB。ADODB也和DB一样,提供了一个抽象的中间层,而且ADODB所支持的后端数据库要比DB多(至少目前如此),不过ADODB没有直接使用PEAR的一些特性,只是吸取了PEAR的许多思想,包括DB,因此二者的使用方法有许多相似的地方。我不想评论二者孰优孰劣,大家可以根据个人的喜好来使用。
二、 为什么要设计抽象的中间数据层
在详细讨论DB的使用之前,我们先讨论一下为什么要设计中间的数据层,因为这意味着你需要作出一些牺牲和让步,比如,你需要多写一些代码,有的局限于特定数据库的特性将无法直接使用。
我们回忆一下我们过去的做法,如何连接到MYSQL数据库?这的确是个小儿科的问题,下面的代码你一定很熟悉:
/**
* 连接到MYSQL数据库
*/
$host = "localhost";
$user = "root";
$passwd = "";
$persistent = 1;
if ($persisternt){
$conn = mysql_connect($host,$user,$passwd);
}else {
$conn = mysql_pconnect($host,$user,$passwd);
}
?>
好了,现在建立了数据库连接,我们可以使用它来进行数据库的操作,我们可能使用类似的代码:
function sql_exec($sql) {
global $db_Name;
$result = mysql_db_query($db_dbName,$sql);
if (!$result) {
echo mysql_errno(). ": ".mysql_error(). "
$sql
";
exit();
}
return $result;
}
$db_Name = "test";
$sql = "select * from users";
$result = sql_exec($sql);
while( $row = mysql_fetch_row($result) ){
echo "姓名:$row[0] 性别:$row[1] 年龄 $row[2]
";
}
mysql_free_result($result);
?>
看起来很不错,是吗?你可能在你的代码里使用很多类似的代码片段。但是,不要太高兴,问题来了。假如,突然,你的数据库需要从MYSQL迁移到别的数据库平台,比如ORACLE,SYBASE。迁移的原因很多,也许是你的老板突发奇想,认为这样能卖个好价钱,或者是你的数据猛增,导致MYSQL的性能下降,总之,迁移是事在必行了。你怎么做,你也许会想,呵呵,这简单,把相关的函数替换一下不就行了。
听起来简单,但是……首先,连接数据库的函数要改,需要把mysql_connect和mysql_pconnect替换成OCILogon和OCIPLogon。mysql_errno和mysql_error()当然不能使用,你需要从OCIError()返回的数组中提取响应的信息。
这还不是太糟,最糟的是相关的mysql_fetch_row,mysql_fetch_array等语句遍布于你的许多代码函数和过程中,你需要逐一查找,分析,然后重新替换或者编写相应的ORACLE的版本。如果,你的数据库操作是集中在一个某一个模块或类中,这项工作还可以接受,否则,等于你重新阅读和修改了绝大部分的代码。即使这个不幸的人不是你,那么他也会暗地里诅咒你的;=)
以上,我们回忆了我们以前的做法,以及可能带来的不幸。那么,如果使用DB类来做类似的操作,应该是什么样的呢?下面是相应的DB版本代码:
include_once "DB.php";
/*
* 连接到数据库
*/
$db_host = "localhost";
$db_user = "root";
$db_passwd = "";
$db_dbName = "test";
$PersistentConnection = 1 ;
$db_type ="mysql";
$db_proto ="";
$db = DB::connect("$db_type://$db_user@$db_passwd:$db_host/$db_dbName",$db_options);
if( DB::isError($db) ){
die "无法连接数据库,错误原因:".DB::errorMessage($db);
}
function sql_exec($sql) {
global $db;
$result = $db->query($sql);
if (DB::isError($result)){
echo "发生数据库错误:".DB::errorMessage($result);
exit();
}
return $result;
}
/////////////////////////////////////////////
$sql = "select * from users";
$result = sql_exec($sql);
while( $row = $result->fetchRow() ){
echo "姓名:$row[0] 性别:$row[1] 年龄 $row[2]
";
}
?>
除了连接数据库部分,其他的看起来只是有一些微小的变化,出错处理使用的是PEAR类似的方式(isError),实际上也是从PEAR继承来的。同样的情况,如果你要把数据库从mysql迁移到别的形式,这次假如说是PostegreSQL,一个LINUX中很优秀的数据库,你所做的只是改变一行代码:
$db_type ="mysql";
变成:
$db_type ="pgsql";
其他的,不用变动。怎么样,升级的感觉是不是很清爽呢,你可以用剩下的时间好好研读其余的代码,或者和我继续往下讨论DB的使用方法。
三、 DB的使用入门
DB类由3部分组成:
DB.php 这是前端接口,在DB类里提供了许多"静态"的公用方法,我们一般只需要INCLUDE_ONCE这个文件就可以了。
DB/common.php 这是后端数据库的通用抽象类,不同的数据库的后端类需要继承并实现这个类中定义的公用方法和属性,如果你的数据库不被支持,你可以自己编写一个支持类,这样,你的应用程序就可以迁移过来了。
DB/storage.php 这是一个辅助的工具,它可以把SQL查询做为对象返回,同时能够维护这些对象,在对象改变的时候,相应地更新数据库。
DB/ifx.php
mssql.php Ms SQL Server支持类
oci8.php Orcale 8i支持类
pgsql.php PostegreSQL支持类
sybase.php Sybase支持类
ibase.php ibase支持类
msql.php mSQL 支持类
mysql.php mysql支持类
odbc.php odbc 支持类
这些是相应后端数据库的支持类了。相应具体的数据库的操作是由这些支持类来实现的。
下面,我们首先详细介绍DB.PHP中的一些"静态"方法:
connect()方法
这个方法是最重要的静态方法了,我们通过得到一个DB_COMMON对象,并且连接到相应的数据库。这个方法的原型如下:
function &connect($dsn, $options = false)
$dsn是数据源名称(data source name)的缩写,可以是字符串,或者是特定的数组形式。
一般来说,$dsn是一个字符串,它的格式如下:
phptype(dbsyntax)://username:password@protocol+hostspec/database
* phptype: php后端数据库的类型名称(如mysql, odbc 等等.)
* dbsyntax: 数据库所使用的SQL语法标准,一般不用。
* protocol: 使用的通讯协议。(如tcp, unix 等等.)
* hostspec: 数据库所在的主机的描述。(形式是:主机名[:端口号])
* database: 数据库的名称。
* username: 登陆的用户名。
* password: 登陆的密码。
对于DSN,常用的形式如下:
* phptype://username:password@protocol+hostspec:110//usr/db_file.db
* phptype://username:password@hostspec/database_name
* phptype://username:password@hostspec
* phptype://username@hostspec
* phptype://hostspec/database
* phptype://hostspec
* phptype(dbsyntax)
* phptype
对于省略的部分,将使用缺省值。
当然,$dsn也可以是一个数组,数组的形式如下:
$dsn = array(
'phptype' => 'mysql',
'dbsyntax' => '',
'protocol' => '',
'hostspec' => 'localhost',
'database' => 'test',
'username' => 'root',
'password' => ''
)
$options 是数据库的选项,混合型。如果是布尔型,那么一般来说,这个参数指明是否使用持久性连接(persistent connect),如果后端数据库支持,当$options是TRUE的时候,将使用持久性连接。如果是数组,那么表示这是特定的后端数据库的选项,这些选项将传递到DB_common类中的set_option方法中,后端数据库通过实现或重载这个方法,可以自己决定如何使用这些选项。
isError($value)
这个方法用来判断DB的一些方法返回的结果是否是一个错误对象,你可以使用这个方法来判定某个操作的结果是否是抛出了异常。
当然,如果你的应用程序从是PEAR继承的,也可以直接使用PEAR的isError来判断,尤其是当你的程序中抛出的异常的可能是数据库以外的异常的时候,这个方法只能判断是否是DB_Errro对象,其他的PEAR_Error对象是无法识别出的。
function isWarning($value)
这个方法是判断DB方法的返回结果是否是一个警告。和错误不同的是,警告不是致命的,所以仍可以继续执行下去。
function errorMessage($value)
一旦确定出现了错误,那么可以使用这个方法来取得相应的错误信息,下面是DB中的预定义的错误信息:
DB_ERROR => "unknown error",
DB_ERROR_ALREADY_EXISTS => "already exists",
DB_ERROR_CANNOT_CREATE => "can not create",
DB_ERROR_CANNOT_DELETE => "can not delete",
DB_ERROR_CANNOT_DROP => "can not drop",
DB_ERROR_CONSTRAINT => "constraint violation",
DB_ERROR_DIVZERO => "division by zero",
DB_ERROR_INVALID => "invalid",
DB_ERROR_INVALID_DATE => "invalid date or time",
DB_ERROR_INVALID_NUMBER => "invalid number",
DB_ERROR_MISMATCH => "mismatch",
DB_ERROR_NODBSELECTED => "no database selected",
DB_ERROR_NOSUCHFIELD => "no such field",
DB_ERROR_NOSUCHTABLE => "no such table",
DB_ERROR_NOT_CAPABLE => "DB backend not capable",
DB_ERROR_NOT_FOUND => "not found",
DB_ERROR_NOT_LOCKED => "not locked",
DB_ERROR_SYNTAX => "syntax error",
DB_ERROR_UNSUPPORTED => "not supported",
DB_ERROR_VALUE_COUNT_ON_ROW => "value count on row",
DB_OK => "no error",
DB_WARNING => "unknown warning",
DB_WARNING_READ_ONLY => "read only"
assertExtension($name)
动态载入PHP的数据库扩展。$name是你的PHP扩展的名称,不包含扩展名(如.dll,.so)。
当你需要让PHP载入某个数据库的扩展,但是你没有权限修改php.ini的时候,可以使用这个函数。
当然,DB内部也是自动调用这个方法来载入所需的PHP数据库的扩展。
比如:你如果需要加载oracle的扩展,那么可以这样使用:
include_once "DB.php";
if ( DB::assertExtension("php_oci8") ){
echo "oracle 8扩展加载成功!";
}else {
die "无法加载oracle 8扩展";
}
?>
以上是在DB类中定义的"静态"方法,所谓静态方法,是指你可以不需要构建对象,就可以直接使用,并且只要你指明DB::,你可以在任何地方直接调用这些方法。
在DB.php中,除了DB外,也有几个非常重要的类,在后端数据库中也使用了这些类:
DB_Error
这个类是从PEAR_Error继承来的,在数据库操作中,对于出现的致命的错误,一般会抛出这个错误。
构建函数:
function DB_Error($code = DB_ERROR, $mode = PEAR_ERROR_RETURN, $level = E_USER_NOTICE, $debuginfo = null)
$code是DB错误代码,$mode决定错误处理的模式,缺省是返回,$level 错误级别,
$debuginfo是附加的调式信息,如刚刚执行的SQL语句等等。
DB_Warning
类似DB_Error。
DB_result
这是非常重要的类。
当执行相应的SQL查询后,后端的数据库类将返回一个DB_result的对象实例,你可以使用这个类的方法来获得查询结果的数据。这个类实际上是后端数据库结果集的包装,这里说的方法,在实际运行中是直接调用了后端数据库的同名的方法,不过,对于我们来说,使用这个包装类会感觉更自然一些。
function fetchRow($fetchmode = DB_FETCHMODE_DEFAULT)
取得一行数据,$fetchmod是获取数据的模式,如果没有指定,那么使用缺省方式。其余的方式我们在后面讨论DB_Common接口的时候会详细讨论。
function fetchInto(&$arr, $fetchmode = DB_FETCHMODE_DEFAULT)
取得一行数据,同时追加到给定的$att数组中。$att是要追加到的数组,它是按照引用方式传递的。
function numCols()
取得结果集的列数。如果出错,返回DB_Error对象。
function numRows()
取得结果集的行数。如果出错,返回DB_Error对象。
function free()
释放结果集所占用的资源。
至此,我们已经学习了DB基本的使用方法,下面我们简单复习一下,对于其中没有见到的方法,我们在后面会详细介绍:
连接数据库:
$db = DB::connect("$db_type://$db_user@$db_passwd:$db_host/$db_dbName",$db_options);
if (DB::isError($db)){
echo "数据库连接错误:".DB::errorMessage($db)."
";
exit();
}
/* 查询1 */
$sql = "select * from user_log";
$result = $db->query($sql);
if (DB::isError($result) ){
echo "数据库错误:".DB::errorMessage($result);
exit();
}
$colCount = $result->numCols();
echo "
while($row = $result->fetch()){
echo "
";
for($i=0;$i echo "
";
}
echo "
";
}
$result->free();
$db->disconnect();
?>
四、 DB_Common 使用参考
DB_Common类是一个通用的接口,DB跨数据库平台的能力是通过实现这个接口来做到的。如果你的数据库不在DB支持之列,你可以自己编写一个类继承DB_Common类,实现这些接口的函数。
function toString()
返回当前类的字符串描述,格式是类名:(phptype="",dbsyntax="")[connected],一般是类似于:
DB_mysql:(phptype=mysql,dbsyntax=)[connected]
function quoteString($string)
圈引一个字符串,使之在查询中能够安全地放在单引号的分界符之间。一般对于字符型的字段,我们查询的时候使用''作为分隔符,因此如果字符串中有'则会出错,这个函数把字符串中的'替换成\'.
function provides($feature)
指明当前DB的后端程序是否实现了给定的特性,返回布尔值。$feature是功能的明称,一般是:"prepare","pconnect","transactions".在后端程序的构建函数中应该设置这些值。例子:
if($db->provider("transactions")){
//支持事务
}else {
//不支持事务
}
function errorCode($nativecode)
用于将后端数据库产生的错误代码映射到DB的通用错误代码中去。内部调用。后端数据库在构建函数中应该初始化$errorcode_map属性。例子(mysql):
//在DB_mysql的构建函数中
$this->errorcode_map = array(
1004 => DB_ERROR_CANNOT_CREATE,
1005 => DB_ERROR_CANNOT_CREATE,
1006 => DB_ERROR_CANNOT_CREATE,
1007 => DB_ERROR_ALREADY_EXISTS,
1008 => DB_ERROR_CANNOT_DROP,
1046 => DB_ERROR_NODBSELECTED,
1050 => DB_ERROR_ALREADY_EXISTS,
1051 => DB_ERROR_NOSUCHTABLE,
1054 => DB_ERROR_NOSUCHFIELD,
1062 => DB_ERROR_ALREADY_EXISTS,
1064 => DB_ERROR_SYNTAX,
1100 => DB_ERROR_NOT_LOCKED,
1136 => DB_ERROR_VALUE_COUNT_ON_ROW,
1146 => DB_ERROR_NOSUCHTABLE,
);

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











로그인 화면에 "귀하의 조직에서 PIN 변경을 요구합니다"라는 메시지가 나타납니다. 이는 개인 장치를 제어할 수 있는 조직 기반 계정 설정을 사용하는 컴퓨터에서 PIN 만료 제한에 도달한 경우 발생합니다. 그러나 개인 계정을 사용하여 Windows를 설정하는 경우 이상적으로는 오류 메시지가 나타나지 않습니다. 항상 그런 것은 아니지만. 오류가 발생한 대부분의 사용자는 개인 계정을 사용하여 신고합니다. 조직에서 Windows 11에서 PIN을 변경하도록 요청하는 이유는 무엇입니까? 귀하의 계정이 조직과 연결되어 있을 수 있으므로 이를 확인하는 것이 기본 접근 방식입니다. 도메인 관리자에게 문의하면 도움이 될 수 있습니다! 또한 잘못 구성된 로컬 정책 설정이나 잘못된 레지스트리 키로 인해 오류가 발생할 수 있습니다. 지금 바로

Windows 11은 신선하고 우아한 디자인을 전면에 내세웠습니다. 현대적인 인터페이스를 통해 창 테두리와 같은 미세한 세부 사항을 개인화하고 변경할 수 있습니다. 이 가이드에서는 Windows 운영 체제에서 자신의 스타일을 반영하는 환경을 만드는 데 도움이 되는 단계별 지침을 설명합니다. 창 테두리 설정을 변경하는 방법은 무엇입니까? +를 눌러 설정 앱을 엽니다. Windows개인 설정으로 이동하여 색상 설정을 클릭합니다. 색상 변경 창 테두리 설정 창 11" Width="643" Height="500" > 제목 표시줄 및 창 테두리에 강조 색상 표시 옵션을 찾아 옆에 있는 스위치를 토글합니다. 시작 메뉴 및 작업 표시줄에 강조 색상을 표시하려면 시작 메뉴와 작업 표시줄에 테마 색상을 표시하려면 시작 메뉴와 작업 표시줄에 테마 표시를 켭니다.

기본적으로 Windows 11의 제목 표시줄 색상은 선택한 어두운/밝은 테마에 따라 다릅니다. 그러나 원하는 색상으로 변경할 수 있습니다. 이 가이드에서는 이를 변경하고 데스크톱 환경을 개인화하여 시각적으로 매력적으로 만드는 세 가지 방법에 대한 단계별 지침을 논의합니다. 활성 창과 비활성 창의 제목 표시줄 색상을 변경할 수 있습니까? 예, 설정 앱을 사용하여 활성 창의 제목 표시줄 색상을 변경하거나 레지스트리 편집기를 사용하여 비활성 창의 제목 표시줄 색상을 변경할 수 있습니다. 이러한 단계를 알아보려면 다음 섹션으로 이동하세요. Windows 11에서 제목 표시줄 색상을 변경하는 방법은 무엇입니까? 1. 설정 앱을 사용하여 +를 눌러 설정 창을 엽니다. Windows"개인 설정"으로 이동한 다음

Windows Installer 페이지에 "OOBELANGUAGE" 문과 함께 "문제가 발생했습니다."가 표시됩니까? 이러한 오류로 인해 Windows 설치가 중단되는 경우가 있습니다. OOBE는 즉시 사용 가능한 경험을 의미합니다. 오류 메시지에서 알 수 있듯이 이는 OOBE 언어 선택과 관련된 문제입니다. 걱정할 필요가 없습니다. OOBE 화면 자체에서 레지스트리를 편집하면 이 문제를 해결할 수 있습니다. 빠른 수정 – 1. OOBE 앱 하단에 있는 “다시 시도” 버튼을 클릭하세요. 그러면 더 이상의 문제 없이 프로세스가 계속됩니다. 2. 전원 버튼을 사용하여 시스템을 강제 종료합니다. 시스템이 다시 시작된 후 OOBE가 계속되어야 합니다. 3. 인터넷에서 시스템 연결을 끊습니다. 오프라인 모드에서 OOBE의 모든 측면을 완료하세요.

작업 표시줄 축소판은 재미있을 수도 있지만 주의를 산만하게 하거나 짜증나게 할 수도 있습니다. 이 영역 위로 얼마나 자주 마우스를 가져가는지 고려하면 실수로 중요한 창을 몇 번 닫았을 수도 있습니다. 또 다른 단점은 더 많은 시스템 리소스를 사용한다는 것입니다. 따라서 리소스 효율성을 높일 수 있는 방법을 찾고 있다면 비활성화하는 방법을 알려드리겠습니다. 그러나 하드웨어 사양이 이를 처리할 수 있고 미리 보기가 마음에 들면 활성화할 수 있습니다. Windows 11에서 작업 표시줄 축소판 미리 보기를 활성화하는 방법은 무엇입니까? 1. 설정 앱을 사용하여 키를 탭하고 설정을 클릭합니다. Windows에서는 시스템을 클릭하고 정보를 선택합니다. 고급 시스템 설정을 클릭합니다. 고급 탭으로 이동하여 성능 아래에서 설정을 선택합니다. "시각 효과"를 선택하세요.

Windows 11의 디스플레이 크기 조정과 관련하여 우리 모두는 서로 다른 선호도를 가지고 있습니다. 큰 아이콘을 좋아하는 사람도 있고, 작은 아이콘을 좋아하는 사람도 있습니다. 그러나 올바른 크기 조정이 중요하다는 점에는 모두가 동의합니다. 잘못된 글꼴 크기 조정이나 이미지의 과도한 크기 조정은 작업 시 생산성을 저하시킬 수 있으므로 시스템 기능을 최대한 활용하려면 이를 사용자 정의하는 방법을 알아야 합니다. Custom Zoom의 장점: 화면의 텍스트를 읽기 어려운 사람들에게 유용한 기능입니다. 한 번에 화면에서 더 많은 것을 볼 수 있도록 도와줍니다. 특정 모니터 및 응용 프로그램에만 적용되는 사용자 정의 확장 프로필을 생성할 수 있습니다. 저사양 하드웨어의 성능을 향상시키는 데 도움이 될 수 있습니다. 이를 통해 화면의 내용을 더 효과적으로 제어할 수 있습니다. 윈도우 11을 사용하는 방법

많은 사용자들이 스마트 시계를 선택할 때 Huawei 브랜드를 선택하게 됩니다. 그 중 Huawei GT3pro와 GT4가 가장 인기 있는 선택입니다. 두 제품의 차이점을 궁금해하는 사용자가 많습니다. Huawei GT3pro와 GT4의 차이점은 무엇입니까? 1. 외관 GT4: 46mm와 41mm, 재질은 유리 거울 + 스테인레스 스틸 본체 + 고해상도 섬유 후면 쉘입니다. GT3pro: 46.6mm 및 42.9mm, 재질은 사파이어 유리 + 티타늄 본체/세라믹 본체 + 세라믹 백 쉘입니다. 2. 건강한 GT4: 최신 Huawei Truseen5.5+ 알고리즘을 사용하면 결과가 더 정확해집니다. GT3pro: ECG 심전도, 혈관 및 안전성 추가

화면 밝기는 최신 컴퓨팅 장치를 사용할 때 필수적인 부분이며, 특히 화면을 장시간 볼 때 더욱 그렇습니다. 눈의 피로를 줄이고, 가독성을 높이며, 콘텐츠를 쉽고 효율적으로 보는 데 도움이 됩니다. 그러나 설정에 따라 밝기 관리가 어려울 수 있으며, 특히 새로운 UI 변경이 적용된 Windows 11에서는 더욱 그렇습니다. 밝기를 조정하는 데 문제가 있는 경우 Windows 11에서 밝기를 관리하는 모든 방법은 다음과 같습니다. Windows 11에서 밝기를 변경하는 방법 [10가지 설명] 단일 모니터 사용자는 다음 방법을 사용하여 Windows 11에서 밝기를 조정할 수 있습니다. 여기에는 단일 모니터를 사용하는 데스크탑 시스템과 노트북이 포함됩니다. 시작하자. 방법 1: 알림 센터 사용 알림 센터에 액세스할 수 있습니다.
