以下是15个PDO类的完整说明及逻辑闭环示例,每个方法均附带功能说明:
1. PDO::beginTransaction()
事务启动方法,开启原子操作单元
// 银行转账事务处理
$db->beginTransaction();
try {
$db->exec("UPDATE accounts SET balance = balance - 100 WHERE user_id = 1");
$db->exec("UPDATE accounts SET balance = balance + 100 WHERE user_id = 2");
$db->commit();
echo "转账成功";
} catch (Exception $e) {
$db->rollBack();
echo "转账失败:" . $e->getMessage();
}2. PDO::commit()
提交事务使操作永久生效
// 订单库存联动处理
$db->beginTransaction();
$orderCreated = $db->exec("INSERT INTO orders VALUES (...)");
$inventoryUpdated = $db->exec("UPDATE products SET stock = stock - 1");
if ($orderCreated && $inventoryUpdated) {
$db->commit();
echo "订单处理完成";
} else {
$db->rollBack();
echo "库存不足,订单取消";
}3. PDO::__construct()
创建数据库连接实例的核心方法
// 安全数据库连接配置
try {
$db = new PDO(
'mysql:host=db.example.com;dbname=ecommerce;charset=utf8mb4',
'secure_user',
'encrypted_pass123',
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false
]
);
echo "数据库连接成功";
} catch (PDOException $e) {
die("连接失败: " . $e->getMessage());
}4. PDO::errorCode()
获取SQL标准错误代码
// SQL错误诊断流程
$result = $db->exec("SELECT * FROM non_existent_table");
if ($result === false) {
if ($db->errorCode() === '42S02') {
echo "错误:数据表不存在";
} else {
echo "未知数据库错误,代码:" . $db->errorCode();
}
}5. PDO::errorInfo()
获取包含错误详情的数组
// 详细错误日志记录
$stmt = $db->prepare("SELECT * FROM users WHERE id = ?");
if (!$stmt->execute([$invalidId])) {
$errorData = $db->errorInfo();
file_put_contents('dberrors.log',
date('Y-m-d H:i:s') . " | SQLSTATE: {$errorData[0]} | 错误码: {$errorData[1]} | 消息: {$errorData[2]}\n",
FILE_APPEND
);
echo "系统错误,日志已记录";
}6. PDO::exec()
执行无结果集的SQL指令
// 用户批量状态更新
$thresholdDate = date('Y-m-d', strtotime('-1 year'));
$affectedRows = $db->exec("
UPDATE users
SET status = 'inactive'
WHERE last_login < '$thresholdDate'
");
echo "已将 {$affectedRows} 个休眠账户标记为停用";7. PDO::getAttribute()
获取数据库连接属性
// 连接参数诊断工具
$driver = $db->getAttribute(PDO::ATTR_DRIVER_NAME);
$version = $db->getAttribute(PDO::ATTR_SERVER_VERSION);
$timeout = $db->getAttribute(PDO::ATTR_TIMEOUT);
echo "连接诊断:{$driver}驱动 | 版本{$version} | 超时{$timeout}秒";
if ($timeout < 10) {
echo "警告:超时设置过低!";
}8. PDO::getAvailableDrivers()
获取环境支持的PDO驱动列表
// 部署环境兼容性检查
$requiredDrivers = ['mysql', 'pgsql'];
$availableDrivers = PDO::getAvailableDrivers();
if (count(array_intersect($requiredDrivers, $availableDrivers)) < 2) {
die("环境不兼容,缺失必要数据库驱动");
}
echo "环境检查通过,支持所有数据库类型";9. PDO::inTransaction()
检测当前是否处于事务中
// 事务安全操作封装
function executeInTransaction($db, $sql) {
if (!$db->inTransaction()) {
throw new LogicException("此操作必须在事务中执行");
}
return $db->exec($sql);
}
try {
$db->beginTransaction();
executeInTransaction($db, "UPDATE audit_log SET status=1");
$db->commit();
} catch (Exception $e) {
$db->rollBack();
echo "操作终止:" . $e->getMessage();
}10. PDO::lastInsertId()
获取最后插入的自增ID
// 订单系统级联创建
$db->beginTransaction();
$db->exec("INSERT INTO orders (customer_id, amount) VALUES (123, 99.99)");
$orderId = $db->lastInsertId();
$db->exec("INSERT INTO order_items (order_id, product_id) VALUES ($orderId, 456)");
$db->exec("INSERT INTO order_items (order_id, product_id) VALUES ($orderId, 789)");
$db->commit();
echo "订单 #$orderId 创建成功,包含明细记录";11. PDO::prepare()
创建防止SQL注入的预处理对象
// 安全登录验证系统
$stmt = $db->prepare("SELECT id, username FROM users WHERE username = ? AND password = SHA2(?, 256)");
$stmt->execute([$_POST['username'], $_POST['password']]);
if ($user = $stmt->fetch()) {
session_regenerate_id();
$_SESSION['user'] = $user;
echo "登录成功,欢迎{$user['username']}";
} else {
http_response_code(401);
echo "身份验证失败";
}12. PDO::query()
执行SQL并返回结果集对象
// 产品分页展示系统
$page = max(1, (int)($_GET['page'] ?? 1));
$perPage = 20;
$offset = ($page - 1) * $perPage;
$result = $db->query("
SELECT id, name, price
FROM products
WHERE stock > 0
ORDER BY created_at DESC
LIMIT $perPage OFFSET $offset
");
echo "第{$page}页产品列表:";
while ($row = $result->fetch()) {
echo "{$row['name']} - ¥{$row['price']}";
}13. PDO::quote()
字符串SQL转义(建议优先预处理)
// 动态搜索功能(历史兼容场景)
$userInput = "O'Reilly Books";
$safeInput = $db->quote("%$userInput%");
$results = $db->query("
SELECT title, author
FROM books
WHERE title LIKE $safeInput
")->fetchAll();
echo "找到" . count($results) . "本匹配'$userInput'的书籍";14. PDO::rollBack()
回滚当前事务
// 库存原子操作
$db->beginTransaction();
try {
$stmt = $db->prepare("SELECT stock FROM products WHERE id=? FOR UPDATE");
$stmt->execute([$productId]);
$stock = $stmt->fetchColumn();
if ($stock < $requestedQty) {
throw new RuntimeException("库存不足,仅剩{$stock}件");
}
$db->exec("UPDATE products SET stock=stock-$requestedQty WHERE id=$productId");
$db->commit();
echo "库存扣减成功";
} catch (Exception $e) {
$db->rollBack();
echo "操作失败:" . $e->getMessage();
}15. PDO::setAttribute()
设置数据库连接属性
// 连接参数优化配置
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
// 配置验证测试
try {
$db->query("INVALID SQL SYNTAX");
} catch (PDOException $e) {
echo "配置生效:异常已捕获 - " . $e->getMessage();
}设计特点
功能闭环:每个示例包含完整业务场景(转账/订单/登录等)
安全防护:事务控制、预处理防注入、错误处理
实际应用:分页查询、批量更新、原子操作等常见场景
错误处理:try-catch异常捕获+事务回滚机制
最佳实践:禁用模拟预处理(ATTR_EMULATE_PREPARES)等安全设置