logo

额外区块类型 (EBT) - 全新的布局构建器体验❗

额外区块类型 (EBT) - 样式化、可定制的区块类型:幻灯片、标签页、卡片、手风琴等更多类型。内置背景、DOM Box、JavaScript 插件的设置。立即体验布局构建的未来。

演示 EBT 模块 下载 EBT 模块

❗额外段落类型 (EPT) - 全新的 Paragraphs 体验

额外段落类型 (EPT) - 类似的基于 Paragraph 的模块集合。

演示 EPT 模块 滚动

滚动

在 Drupal 7 中操作数据库 - 第1课 - Drupal 数据库 API(DB API)

14/10/2025, by Ivan

如果你曾经为 Drupal 6 编写过模块,那么迁移到新的 Drupal 7 Database API 对你来说不会太困难。新的数据库 API 基于 PHP 的 PDO 扩展,这使它能够支持多种数据库,例如 MySQL、PostgreSQL、MSSQL,甚至可能包括 Oracle。虽然语法需要一些时间去适应,但从安全性和可扩展性角度来看,它比直接书写 SQL 更强大。

以下是官方文档中的一些要点:

Drupal 7 Database API 提供了一个标准化且直观的数据库访问抽象层。该 API 在尽可能保持 SQL 语法和灵活性的同时,还提供了以下特性:

  • 轻松支持多个数据库服务器;
  • 允许开发者使用更复杂的数据库功能(如事务);
  • 提供结构化接口,用于动态构建 SQL 查询;
  • 增强安全性并遵循良好的开发实践;
  • 为模块提供清晰的接口,用于拦截和修改站点查询;
  • 主要文档直接包含在源码注释中,Handbook 提供模块开发者级别的入门指南,但并未涵盖 API 的所有功能;
  • Database API 基于面向对象(OOP)概念实现,建议开发者具备一定的 OOP 基础。不过,大多数常见操作也可通过过程式函数实现。

Drupal Database API 的核心概念

Drupal 的数据库抽象层(db layer)基于 PHP PDO 库。PDO 为多种数据库提供统一的面向对象接口,但并不抽象不同 SQL 方言之间的差异。因此,Drupal 通过为不同数据库定义驱动(driver)来实现兼容性。

数据库驱动(Drivers)

由于不同数据库的交互方式不同,Drupal 的 DB 层为每种数据库类型提供独立驱动。驱动文件存放在 includes/database/driver 目录下,其中 driver 是该驱动的唯一标识。例如常见的有 “mysql”、 “pgsql” 或 “mycustomdriver”。

每个驱动包含多个类,这些类继承自系统核心中的父类,可以根据数据库特性重写其行为。命名规则通常为 类名_驱动名,例如:MySQL 专用的插入类命名为 InsertQuery_mysql

数据库连接(Connection)

每个数据库连接都是一个 DatabaseConnection 对象,该类继承自 PHP 的 PDO 类。Drupal 为每个连接的数据库维护一个独立的连接对象。不同驱动可以通过继承来实现各自的连接类。

获取连接对象的方式如下:

<?php
$conn = Database::getConnection($target, $key);
?>

如果要获取当前活动的连接,只需:

<?php
$conn = Database::getConnection();
?>

在大多数情况下,你无需直接操作连接对象,因为 Drupal 的过程式包装函数(如 db_query())会自动处理连接。只有在跨多个数据库执行复杂查询时,才需要手动切换连接。

切换活动连接可使用:

<?php
db_set_active($key);
?>

数据库查询(Queries)

查询是要通过数据库连接执行的 SQL 语句。Drupal DB API 支持六种主要的查询类型:

  • Static(静态查询)
  • Dynamic(动态查询)
  • Insert(插入)
  • Update(更新)
  • Delete(删除)
  • Merge(合并)

这些查询可以通过 SQL 字符串直接执行,也可以使用 Drupal 的对象式查询构建器。对象式查询提供更高的安全性和灵活性。

构建查询对象

查询对象的声明通常始于一个 SELECT 查询。所有查询对象均继承自 DatabaseStatement 类(该类扩展自 PDOStatement)。

Drupal 默认使用“预处理语句”(Prepared Statements),即在查询中使用占位符,值在执行时绑定。这不仅提高了执行效率,还能防止 SQL 注入攻击。

例如,在 PDO 中,一个预处理语句模板可以重复执行,每次使用不同的绑定参数。Drupal 将这一机制封装在自己的查询对象中,开发者无需直接操作 PDO 的底层方法。

换句话说,Drupal 不暴露底层的 PDO 预处理接口,而是通过自身的对象封装实现这一功能。开发者只需编写结构化查询,无需手动绑定参数。