游乐游手机版
首页/数据库/文章详情

PEAR DB将数据库工作简化

时间:2026-04-30 18:29
有经验的PHPer应该对PEAR*都不会陌生,不过对新手来说,简单的练习PEAR应该不必派上用场,不过在开始接触复杂的编程时,PEAR对PHPer来说可以说是一个很有效的工具。 到底什么是PEAR?详细的答案都在pear php net上,这里就不多赘述了。不过,有一个工具值得重点介绍,它就是DB—

有经验的PHPer应该对PEAR*都不会陌生,不过对新手来说,简单的练习PEAR应该不必派上用场,不过在开始接触复杂的编程时,PEAR对PHPer来说可以说是一个很有效的工具。

到底什么是PEAR?详细的答案都在pear.php.net上,这里就不多赘述了。不过,有一个工具值得重点介绍,它就是DB——一个构建在PEAR之上的数据库抽象层。

PHP本身虽然提供了内置的数据库函数,但功能相对有限,而且在平台迁移时麻烦不小。比如,连接MySQL用的是mysql_connect(),而连接PostgreSQL则要用pg_connect()。如果你的程序只是小打小闹,把所有的mysql_[x]手动改成pg_[x]或许还扛得住。可一旦数据库操作层源码超过500行,这种改动简直就是一场噩梦!要是这些函数还散落在代码的各个角落,那修复起来就更恐怖了。

正因如此,一个跨平台的数据库接口抽象层就显得至关重要。它需要能接管大部分脏活累活,包括连接、查询、更新,最好还能提供调试功能。而PEAR DB,正是这样一个理想的工具。

它支持的数据平台相当广泛,包括dbase, Frontbase, InterBase, Informix, MiniSQL, MSSQL, MySQL, Oracle, ODBC, PostgreSQL, SQLite, Sybase。它完全可以作为PHP程序的整个数据库层,性能表现也相当理想(当然,纯粹论速度可能比直接调用mysql_query()稍慢一点,但在大型项目中,其可维护性和可移植性的优势就凸显出来了)。

PEAR DB的核心功能都封装在三个类里,用法并不复杂。下面就来逐一介绍。

1. DB类

DB类是PEAR DB的骨架,所有函数都以静态方式调用,这意味着你不需要实例化它,直接调用即可。

当配置好上述任意一种数据库后,第一步就是建立连接。这需要用到DB::connect()函数和一个DSN(数据源名称)字符串。DSN的格式如下:

sqltype://username:passwd@protocol+host/database?option=value

示例: $dsn = “mysql://username:passw0rD@localhost/mydb”

其中,Sqltype指数据库平台,具体的字符串可以去DSN文档页面查阅。

接下来,把DSN字符串传给DB::connect()

$conn = & DB::connect($dsn);

if(Pear::isError($conn)){
        die($conn->getMessage());
}

这里的$connDB::connect()返回的一个接口实例,后续它将扮演核心角色。注意下面一段代码,这里使用了PEAR::isError()来检查$conn是否是一个DB error对象。一旦连接出错,$conn会自动携带错误信息。getMessage()这个函数内置于DB error类,可以随时调用。

*通常情况下,PEAR会随PHP一起安装。如果需要单独安装,可以下载PHP完整压缩包,运行里面的do-pear.bat即可。(DB已经包含在PEAR安装包内,无需另外下载。)

2. DB_Common界面

刚才提到的$conn就是这个界面类型的实例。这个界面负责绝大部分的数据操作,包括查询、更新、插入等等。它包含大量功能强大的函数,这里先介绍几个关键的。

-- 查询示例
$sql = “SELECT * FROM blah”;
$conn->setFetchMode(DB_FETCHMODE_ASSOC);

$result = $conn->query($sql);

$row = $result->fetchRow();
print_r($row);

$conn->disconnect();

如果你熟悉PHP原生的数据库方法,对[x]_fetch_assoc应该不会陌生。没错,这里的意思大致相同。DB_Common的默认抓取模式是DB_FETCHMODE_ORDERED,效果类似于[x]_fetch_row。在上面的例子里,我们通过DB_Common::setFetchMode()将其改为DB_FETCHMODE_ASSOC,这样$result的抓取结果就会和[x]_fetch_assoc一样,以字段名作为数组索引。

这里的$result(属于DB_Result类)和mysql_query()返回的资源标识符作用类似,是PEAR DB里另一个重要的类型,稍后会介绍。如果需要获取一行数据,可以使用DB_Result::fetchRow(),它会返回一个包含一行数据的数组。

前面提到的PEAR::isError()同样可以用来检查$result是否有错误:

if(PEAR::isError($result)){
        die($result->getMessage());
}

方法和之前如出一辙,只是检查的对象从DB_Common实例换成了DB_Result实例。

DB_Common还提供了两个非常方便的方法,prepare()execute(),能让PHP轻松处理INSERT和UPDATE操作。这对组合可以让你高效地同时执行多个INSERT或UPDATE语句。prepare()预先载入要执行的SQL模板,而execute()则负责执行,并传入所需参数。看看下面的例子:

$conn->prepare(“INSERT INTO foo (fname, fage, flocation) VALUES (? , ? , ? )”);
$data = array(“foo”, 23, “earth”);
$conn->execute($stn, $data);

if(PEAR::isError($stn)){
        die($stn->getMessage());
}

$conn->freePrepared();

SQL中的“?”是占位符,$data数组里的数据会按顺序替换这些占位符。所有数据都会自动进行转义处理,execute()也能自动识别数字、字符串等数据类型。

那么,如果要插入多行数据呢?能不能简化操作?答案是肯定的。看看下面的例子,你就会发现DB是多么不可思议了:

$conn->prepare(“INSERT INTO foo (fname, fage, flocation) VALUES (? , ? , ? )”);
$data = array(
        array(“foo”, 23, “earth”),
        array(“faa”, 21, “moon”),
        array(“fee”, 25, “mars”),
        array(“fii”, 19, “Pluto”)
);
$conn->executeMultiple($stn, $data);

if(PEAR::isError($stn)){
        die($stn->getMessage());
}

$conn->freePrepared();

原本繁杂的操作,几行代码就搞定了,关键就在$data这个多维数组和DB_Common::executeMultiple()这个方法上。$stnexecute()executeMultiple()返回的结果,它有三种可能:第一是DB_Result对象,可以将查询结果转为实体;第二是预定义常量DB_OK,代表语句执行成功;第三就是DB_Error对象,后面的PEAR::isError()就是检查是否返回了这种错误对象。如果想用同一个DB_Common资源执行另一个查询,必须调用DB_Common::freePrepared()来清除之前prepare()载入的SQL模板。

DB_Common可以说是PEAR DB中最重要的操作界面,大部分和数据库的交互都在这里完成,功能十分强大。除了上面介绍的几个方法,它还有很多其他实用的方法,详细说明可以参考pear.php.net上的文档。

3. DB_Result

顾名思义,DB_ResultDB_Common执行查询后返回的数据集合。DB_Result本身是一个对象,内置了几个非常方便的方法。

-- fetchInto() 和 fetchRow()
这两个方法作用基本相同,唯一区别在于:前者将结果传递给一个引用参数($result->fetchInto(&$row));而后者直接返回结果($row = $result->fetchRow())。和PHP内置函数一样,fetchRow()每次返回一行数据。

-- numCols() 和 numRows()
这两个方法分别返回DB_Result中字段(列)和记录(行)的数量。

-- free()
DB_Result内的数据从内存中释放。

下面这个例子综合运用了以上几种方法:

$conn->setFetchMode(DB_FETCHMODE_ASSOC);
$result = $conn->query($sql);

echo “共找到 “.$result->numRows().” 条结果,包含 “.$result->numCols().” 个字段。”;

while( $row = $result->fetchRow()){
        echo $row[‘name’];
}

$result->free();

后记:
以上内容只是基础介绍,如果想深入了解,可以访问 https://pear.php.net/package/DB PHP PEAR的网页,里面有详细的文档可供参考。除了DB之外,PEAR网站上还提供了各式各样的数据库抽象层供免费下载,包括LDAP、ADODB,还有类似DB的MDB2,也是一个不错的选择。

来源:https://blog.csdn.net/iteye_9193/article/details/81654039
上一篇redis内存持久化机制和淘汰策略使用详解 下一篇MongoDB数据库去重函数Distinct用法实例
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
Redis 7.0增量AOF重写RDB前导码配置详解
数据库 · 2026-07-02

Redis 7.0增量AOF重写RDB前导码配置详解

先说一个几乎所有人都踩过的典型误区:很多人把 aof-use-rdb-preamble yes 当作开启“增量重写”的开关。实际上,这个配置只干了一件事——让重写后的 AOF 文件头部带上 RDB 快照。它解决的是加载速度问题,跟“增量重写”本身的概念压根不是一回事。真正的增量重写,依赖的是 Red

在Python Tornado异步框架中安全执行SQL命令的方法与最佳实践
数据库 · 2026-07-02

在Python Tornado异步框架中安全执行SQL命令的方法与最佳实践

直接在Tornado里用SQLAlchemy同步执行SQL,结果就是阻塞IOLoop,所谓“异步框架里写同步数据库代码”,等于白搭。安全执行的关键不是“怎么写SQL”,而是“怎么不卡住事件循环”。 为什么不能在RequestHandler里直接调用session execute() 因为sessio

利用SQL触发器实现在INSERT数据时自动同步到审计表
数据库 · 2026-07-02

利用SQL触发器实现在INSERT数据时自动同步到审计表

先说结论:可以用触发器把 INSERT 数据同步到审计表,但必须用 AFTER INSERT,并且审计表的字段顺序、类型、字符集得和源表严格一致。否则,轻则写入错位、数据截断,重则直接报错、丢数据。下面把这些坑一个一个掰开说。 能,但必须用 AFTER INSERT,且审计表字段顺序、类型、字符集要

如何用SQL编写按不同工作日统计员工出勤率
数据库 · 2026-07-02

如何用SQL编写按不同工作日统计员工出勤率

在实际业务中,统计不同工作日的出勤率是HR系统里的高频需求。如果直接按日期函数分组,很容易掉进语言环境、索引失效或分母口径的坑里。下面就来拆解具体的实现要点。 必须用 CASE WHEN 将日期映射为固定 weekday 标签(如 Mon )再分组,避免语言环境导致的分组断裂;需过滤 DOW IN

Spring Boot 3动态拼接SQL为何引发严重安全漏洞
数据库 · 2026-07-02

Spring Boot 3动态拼接SQL为何引发严重安全漏洞

SQL注入漏洞的核心成因,本质上是因为用户输入直接参与了SQL语句的字符串拼接,而未采用参数化绑定机制。在MyBatis中使用${}、QueryWrapper中调用apply()与last()、JPA的@Query注解进行拼接等操作,都会绕过PreparedStatement的安全防护。动态字段必须