在 Drupal 7 中操作数据库 - 第3课 - 静态查询(SELECT)
在 Drupal 中最常见的查询形式是静态查询(Static Query)。静态查询会直接、完整地传递给数据库。只有 SELECT 查询可以是静态的。
静态查询仅适用于非常简单的场景。如果你需要构建复杂的、可动态生成或执行后可修改的查询,应该使用动态查询(Dynamic Query)。
执行静态查询的最简单方式是使用查询方法:
<?php $result = $conn->query("SELECT nid, title FROM {node}"); ?>
但更推荐使用过程式封装函数:
<?php $result = db_query("SELECT nid, title FROM {node}"); ?>
上述调用等价于以下语句:
<?php $result = Database::getConnection()->query("SELECT nid, title FROM {node}"); ?>
下面解释为什么 db_query() 比直接访问 Database 对象更好。
db_query() 接受三个参数:
- 查询字符串(可使用占位符 placeholders,并用花括号包裹表名)。
- 占位符数组。
- 可选配置数组,用于定义查询执行方式。
表前缀(Prefix)
在静态查询中,所有表名都应使用 {}
包裹。这允许为表名添加前缀。前缀用于在同一个数据库中安装多个 Drupal 站点。例如表名可分别使用前缀 “site1_”、“site2_”。
占位符(Placeholders)
占位符用于安全地传递变量,以防止 SQL 注入。Drupal 使用冒号(:)前缀来定义占位符。
<?php $result = db_query("SELECT nid, title FROM {node} WHERE created > :created", array( ':created' => REQUEST_TIME - 3600, )); ?>
上例中,查询会选出在过去一小时内创建的节点。:created
会被替换为 REQUEST_TIME - 3600
。查询中可以有多个占位符,每个都需唯一命名。
占位符可嵌入在数组中或单独定义后传入,顺序无关。以 "db_" 开头的占位符名为系统保留,不可使用。
注意,占位符是否加引号取决于数据类型。字符串值应加引号,数字不需要。
<?php // 错误写法: $result = db_query("SELECT nid, title FROM {node} WHERE type = ':type'", array( ':type' => 'page', )); // 正确写法: $result = db_query("SELECT nid, title FROM {node} WHERE type = :type", array( ':type' => 'page', )); ?>
占位符不能用于表名或字段名,只能用于传递文本或数值。
占位符数组(Placeholder Arrays)
Drupal 数据库层支持一个便捷特性:当传入数组时,占位符会自动展开为逗号分隔的值列表。开发者无需手动计数占位符。
<?php db_query("SELECT * FROM {node} WHERE nid IN (:nids)", array(':nids' => array(13, 42, 144))); // Drupal 会自动转换为: db_query("SELECT * FROM {node} WHERE nid IN (:nids_1, :nids_2, :nids_3)", array( ':nids_1' => 13, ':nids_2' => 42, ':nids_3' => 144, )); // 等价于: db_query("SELECT * FROM {node} WHERE nid IN (13, 42, 144)"); ?>
查询参数(Query Options)
db_query() 的第三个参数是配置数组,用于定义查询的执行方式。通常最常用的两个选项是:
- target — 指定查询目标(默认为 “default”)。当值为 “slave” 时,查询会在从服务器上执行(如果可用)。
- fetch — 定义结果返回的格式。
可用的 fetch 值包括:
- PDO::FETCH_OBJ — 返回对象(默认)。
- PDO::FETCH_ASSOC — 返回关联数组。
- PDO::FETCH_NUM — 返回索引数组。
- PDO::FETCH_BOTH — 同时返回索引和关联数组。
- 或自定义类名字符串 — 每条记录作为该类的对象返回。
详细说明可参见 PDO 官方文档。默认使用 PDO::FETCH_OBJ,除非有特殊需要。
以下示例展示如何在从服务器上执行查询,并以关联数组形式获取结果:
<?php $result = db_query("SELECT nid, title FROM {node}", array(), array( 'target' => 'slave', 'fetch' => PDO::FETCH_ASSOC, )); ?>