PHP PDOStatement::setAttribute 方法
最后修改于 2025 年 4 月 19 日
PDOStatement::setAttribute 方法允许为 PDO 预处理语句配置语句级别的属性。它自定义了语句的行为方式。
基本定义
PDOStatement::setAttribute 在语句句柄上设置一个属性。它会影响语句在执行和获取结果时的行为。
语法: public PDOStatement::setAttribute(int $attribute, mixed $value): bool
。成功返回 true,失败返回 false。对于无效属性会抛出 PDOException。
设置所有获取的获取模式
此示例演示如何为所有获取操作设置默认获取模式。
<?php declare(strict_types=1); try { $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password'); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $pdo->prepare('SELECT * FROM users'); $stmt->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); $stmt->execute(); while ($row = $stmt->fetch()) { print_r($row); } } catch (PDOException $e) { echo "Error: " . $e->getMessage(); }
这会将所有获取调用的默认获取模式设置为关联数组。PDO::ATTR_DEFAULT_FETCH_MODE 属性会影响后续的获取操作。
设置游标类型
此示例演示如何为语句执行配置游标类型。
<?php declare(strict_types=1); try { $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password'); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $pdo->prepare('SELECT * FROM large_table'); $stmt->setAttribute(PDO::ATTR_CURSOR, PDO::CURSOR_SCROLL); $stmt->execute(); // Scrollable cursor allows fetching rows in any order $row = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_LAST); print_r($row); } catch (PDOException $e) { echo "Error: " . $e->getMessage(); }
这会设置一个可滚动的游标,允许对结果行进行随机访问。PDO::CURSOR_SCROLL 允许在执行后按任意顺序获取行。
设置查询超时
此示例演示如何为语句执行设置超时。
<?php declare(strict_types=1); try { $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password'); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $pdo->prepare('SELECT * FROM large_table WHERE complex_condition = ?'); $stmt->setAttribute(PDO::ATTR_TIMEOUT, 5); // 5 second timeout $stmt->execute([1]); $results = $stmt->fetchAll(); print_r($results); } catch (PDOException $e) { echo "Error: " . $e->getMessage(); }
这会为查询执行设置 5 秒超时。PDO::ATTR_TIMEOUT 属性指定超时(以秒为单位)。并非所有驱动程序都支持此功能。
设置模拟准备
此示例演示如何控制预处理语句的模拟。
<?php declare(strict_types=1); try { $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password'); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?'); $stmt->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $stmt->execute([42]); $user = $stmt->fetch(); print_r($user); } catch (PDOException $e) { echo "Error: " . $e->getMessage(); }
这会禁用模拟准备,强制使用真正的预处理语句。PDO::ATTR_EMULATE_PREPARES=false 在可能的情况下使用本机数据库准备。
设置字符串化获取
此示例演示在获取时将数值转换为字符串。
<?php declare(strict_types=1); try { $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password'); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $pdo->prepare('SELECT id, name, balance FROM accounts'); $stmt->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); $stmt->execute(); $account = $stmt->fetch(); var_dump($account['balance']); // Will be string even if numeric in DB } catch (PDOException $e) { echo "Error: " . $e->getMessage(); }
这会强制将数值作为字符串返回。PDO::ATTR_STRINGIFY_FETCHES 将所有获取的值转换为字符串。对于严格类型检查非常有用。
设置列大小写
此示例演示如何控制结果集中列名的大小写。
<?php declare(strict_types=1); try { $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password'); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $pdo->prepare('SELECT user_id, user_name FROM users'); $stmt->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER); $stmt->execute(); $user = $stmt->fetch(); // Column names will be lowercase regardless of database case echo $user['user_id']; } catch (PDOException $e) { echo "Error: " . $e->getMessage(); }
这会强制结果集中的列名小写。PDO::ATTR_CASE 与 PDO::CASE_LOWER 一起将所有列名转换为小写。其他选项包括 CASE_UPPER 和 CASE_NATURAL。
设置持久化语句
此示例演示如何使用持久化语句来提高性能。
<?php declare(strict_types=1); try { $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password', [ PDO::ATTR_PERSISTENT => true ]); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $pdo->prepare('SELECT * FROM frequently_accessed'); $stmt->setAttribute(PDO::ATTR_STATEMENT_CLASS, ['MyPDOStatement']); $stmt->execute(); $results = $stmt->fetchAll(); print_r($results); } catch (PDOException $e) { echo "Error: " . $e->getMessage(); } class MyPDOStatement extends PDOStatement { // Custom statement class for persistent connections }
这会使用自定义语句类和持久化连接。PDO::ATTR_STATEMENT_CLASS 指定一个自定义语句类。与持久化连接一起使用,以在请求之间保持状态。
最佳实践
- 使用适当的属性: 选择与您的用例匹配的属性。
- 检查驱动程序支持: 并非所有属性都适用于所有驱动程序。
- 错误处理: 始终处理潜在的 PDOException。
- 性能: 考虑诸如模拟准备之类的属性的影响。
- 可读性: 记录不明显的属性设置。
来源
PHP PDOStatement::setAttribute 文档
本教程介绍了 PDOStatement::setAttribute 方法,并提供了实际示例,展示了预处理语句的各种配置选项。
作者
列出 所有 PHP PDO 函数。