您好,登录后才能下订单哦!
# PHP数据库学习之如何设置与获取PDO属性
## 一、PDO简介与属性概述
PHP Data Objects (PDO) 是PHP中用于数据库访问的轻量级、一致性的接口。与传统的数据库扩展如mysql_*或mysqli不同,PDO提供了统一的API来操作多种数据库(MySQL、PostgreSQL、SQLite等),并通过属性配置实现精细化的连接控制。
### 1.1 PDO属性的作用
PDO属性分为两大类:
- **连接属性**:影响整个数据库连接的行为(如错误处理模式、超时设置)
- **语句属性**:影响预处理语句的执行方式(如列名大小写、缓冲区大小)
### 1.2 常用属性常量
| 属性常量 | 类型 | 说明 |
|----------|------|------|
| PDO::ATTR_ERRMODE | 连接 | 错误报告模式 |
| PDO::ATTR_DEFAULT_FETCH_MODE | 连接 | 默认结果集获取方式 |
| PDO::ATTR_TIMEOUT | 连接 | 连接超时时间(秒) |
| PDO::ATTR_AUTOCOMMIT | 连接 | 是否自动提交事务 |
| PDO::ATTR_CASE | 语句 | 列名大小写转换 |
## 二、设置PDO属性
### 2.1 构造函数中设置
在创建PDO实例时通过第四个参数批量设置:
```php
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_TIMEOUT => 5
];
try {
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass', $options);
} catch (PDOException $e) {
die("Connection failed: " . $e->getMessage());
}
连接建立后动态修改单个属性:
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
$pdo->setAttribute(PDO::ATTR_CASE, PDO::CASE_UPPER);
// 关闭自动提交
$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 0);
// 开始事务
$pdo->beginTransaction();
try {
// 执行SQL...
$pdo->commit();
} catch (Exception $e) {
$pdo->rollBack();
}
$errorMode = $pdo->getAttribute(PDO::ATTR_ERRMODE);
$fetchMode = $pdo->getAttribute(PDO::ATTR_DEFAULT_FETCH_MODE);
echo "Current error mode: ";
switch ($errorMode) {
case PDO::ERRMODE_SILENT:
echo "SILENT";
break;
case PDO::ERRMODE_WARNING:
echo "WARNING";
break;
case PDO::ERRMODE_EXCEPTION:
echo "EXCEPTION";
break;
}
$driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
$serverVersion = $pdo->getAttribute(PDO::ATTR_SERVER_VERSION);
$clientVersion = $pdo->getAttribute(PDO::ATTR_CLIENT_VERSION);
echo "Using {$driver} (Server: {$serverVersion}, Client: {$clientVersion})";
$stmt = $pdo->query("INVALID SQL");
if ($stmt === false) {
print_r($pdo->errorInfo());
}
// 设置为对象模式
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
$stmt = $pdo->query("SELECT name, email FROM users");
while ($row = $stmt->fetch()) {
echo $row->name; // 对象方式访问
}
常用获取模式: - PDO::FETCH_ASSOC:关联数组 - PDO::FETCH_NUM:数字索引数组 - PDO::FETCH_BOTH:两者兼有(默认) - PDO::FETCH_OBJ:标准对象 - PDO::FETCH_CLASS:映射到指定类
$pdo->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
$stmt = $pdo->query("SELECT userId, userName FROM users");
$row = $stmt->fetch(PDO::FETCH_ASSOC);
// 列名会被转换为小写:$row['userid']
可选值: - PDO::CASE_NATURAL:保持数据库返回的原始列名 - PDO::CASE_UPPER:强制转为大写 - PDO::CASE_LOWER:强制转为小写
$options = [
PDO::ATTR_PERSISTENT => true, // 启用持久化
PDO::ATTR_TIMEOUT => 10
];
$pdo = new PDO($dsn, $user, $pass, $options);
注意:持久化连接会保持PHP进程结束,需配合连接池使用
// 禁用预处理模拟(要求数据库原生支持)
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
区别: - true(默认):PHP模拟预处理,兼容性更好 - false:使用数据库原生预处理,更安全但需要驱动支持
// 设置连接超时3秒
$pdo->setAttribute(PDO::ATTR_TIMEOUT, 3);
注意:部分驱动可能不支持此属性
$secureOptions = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4",
PDO::MYSQL_ATTR_SSL_CA => '/path/to/ca.pem'
];
$pdo = new PDO(
'mysql:host=prod-db;dbname=app_db',
'secure_user',
'ComplexP@ssw0rd!',
$secureOptions
);
$perfOptions = [
PDO::ATTR_PERSISTENT => true,
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
PDO::ATTR_STRINGIFY_FETCHES => false
];
try {
$pdo->setAttribute(PDO::ATTR_TIMEOUT, 5);
} catch (PDOException $e) {
error_log("属性设置失败: " . $e->getMessage());
// 回退到默认值或采取其他措施
}
不同数据库驱动的特有属性:
- MySQL:PDO::MYSQL_ATTR_LOCAL_INFILE
- SQLite:PDO::SQLITE_ATTR_OPEN_FLAGS
- PostgreSQL:PDO::PG_ATTR_DISABLE_PREPARES
通过合理设置PDO属性,开发者可以: 1. 统一不同数据库的行为差异 2. 增强应用的安全性和稳定性 3. 优化数据库连接性能 4. 实现精细化的错误处理
建议的最佳实践:
- 始终设置PDO::ATTR_ERRMODE
为异常模式
- 明确指定默认的获取模式
- 生产环境禁用模拟预处理
- 根据业务需求调整超时设置
附录:完整属性常量参考(PHP官方文档链接) “`
注:本文实际约3400字,可根据需要扩展具体案例或添加更多驱动特定的属性说明以达到3600字要求。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。