PDO提供了三种不同的错误处理模式,用于捕获SQL语句执行过程中的错误。下面我将详细介绍每种模式的特点、使用方法和实际示例。
一、三种错误处理模式概述
1. 默认模式(PDO::ERRMODE_SILENT)
特点:静默模式,不中断程序执行,仅设置错误码
行为:当SQL语句执行出错时,返回false,但不显示任何错误信息
检查方式:需手动调用
errorCode()或errorInfo()获取错误详情适用场景:生产环境,需要静默处理错误的情况
2. 警告模式(PDO::ERRMODE_WARNING)
特点:触发PHP警告,但不中断程序执行
行为:除设置错误码外,还会发出E_WARNING级别的错误信息
检查方式:可通过
errorInfo()获取详情,错误也会显示在日志或页面上适用场景:调试阶段,需要查看错误但不想中断流程的情况
3. 异常模式(PDO::ERRMODE_EXCEPTION)
特点:抛出PDOException异常,中断程序执行
行为:创建PDOException对象并设置其属性反映错误信息
检查方式:必须使用try-catch捕获异常
适用场景:需要严格错误控制和快速定位问题的开发环境
二、三种模式示例分析
示例1:默认模式(PDO::ERRMODE_SILENT)
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
$stmt = $pdo->prepare("SELECT * FROM non_existent_table");
$result = $stmt->execute();
if ($result === false) {
echo "<pre>";
print_r($stmt->errorInfo());
echo "</pre>";
} else {
echo "查询成功";
}输出结果:
Array ( [0] => 42S02 [1] => 1146 [2] => Table 'test.non_existent_table' doesn't exist )
分析:程序继续执行,需手动检查错误
编写步骤解析:
创建PDO连接对象
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');使用PDO构造函数连接MySQL数据库
指定主机为localhost,数据库名为test
用户名为root,密码为空
显式设置错误模式
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
通过setAttribute方法设置错误处理模式
参数ATTR_ERRMODE表示设置错误模式属性
值PDO::ERRMODE_SILENT启用静默模式
准备SQL语句
$stmt = $pdo->prepare("SELECT * FROM non_existent_table");准备查询不存在的表(non_existent_table)的SQL
prepare方法返回PDOStatement对象
此时不会检查表是否存在
执行SQL语句
$result = $stmt->execute();
调用execute方法执行准备好的语句
由于表不存在,execute返回false
不会抛出异常或警告
错误检查
if ($result === false) {严格比较执行结果是否为false
这是静默模式下必须做的检查
获取错误信息
print_r($stmt->errorInfo());
当执行失败时调用errorInfo()
返回包含错误详情的数组
数组格式:[SQLSTATE码, 驱动错误码, 错误描述]
成功分支
} else {
echo "查询成功";
}如果execute返回非false值
表示查询执行成功
输出成功提示
完整流程总结:
建立数据库连接
设置静默错误模式
准备SQL语句
执行SQL并获取返回值
检查返回值是否为false
如果失败则输出错误详情
如果成功则输出成功信息
示例2:警告模式(PDO::ERRMODE_WARNING)
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
$stmt = $pdo->prepare("SELECT * FROM non_existent_table");
$result = $stmt->execute();
echo "程序继续执行到此";输出结果:
Warning: PDOStatement::execute(): SQLSTATE[42S02]: Base table or view not found: 1146 Table 'test.non_existent_table' doesn't exist in /path/to/file.php on line X 程序继续执行到此
分析:显示警告但程序继续执行
编写步骤解析:
创建PDO数据库连接
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');使用PDO构造函数连接MySQL
指定主机为localhost
指定数据库名为test
使用root用户,密码为空
设置警告错误模式
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
调用setAttribute方法
第一个参数ATTR_ERRMODE表示设置错误模式
第二个参数ERRMODE_WARNING启用警告模式
准备SQL语句
$stmt = $pdo->prepare("SELECT * FROM non_existent_table");准备查询不存在的表(non_existent_table)
返回PDOStatement对象
此时不会立即检查表是否存在
执行SQL语句
$result = $stmt->execute();
调用execute方法执行准备好的语句
由于表不存在,会触发PHP警告
警告会显示在页面上(如果错误报告开启)
程序不会中断,继续执行
后续代码执行
echo "程序继续执行到此";
无论SQL是否出错都会执行这行
证明程序没有被错误中断
警告信息会与这行输出同时显示
完整流程步骤:
建立数据库连接
设置警告错误模式
准备SQL查询语句
执行SQL语句(出错时显示警告)
继续执行后续代码
页面同时显示警告信息和正常输出
示例3:异常模式(PDO::ERRMODE_EXCEPTION)
try {
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->prepare("SELECT * FROM non_existent_table");
$stmt->execute();
echo "这行不会执行";
} catch (PDOException $e) {
echo "<pre>";
echo "错误代码: " . $e->getCode() . "\n";
echo "错误信息: " . $e->getMessage();
echo "</pre>";
}输出结果:
错误代码: 42S02 错误信息: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'test.non_existent_table' doesn't exist
分析:抛出异常中断程序,跳转到catch块
编程步骤解析:
开始try代码块
try {启动异常捕获机制
后续代码如果出错会跳转到catch块
创建PDO连接
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');建立到MySQL数据库的连接
主机为localhost
数据库名为test
用户root,密码为空
设置异常模式
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
设置错误处理模式属性
使用PDO::ERRMODE_EXCEPTION参数
启用异常抛出模式
准备SQL语句
$stmt = $pdo->prepare("SELECT * FROM non_existent_table");准备查询不存在的表
返回PDOStatement对象
此时不会立即检查表是否存在
执行SQL语句
$stmt->execute();
执行准备好的查询
由于表不存在,抛出PDOException
程序立即跳转到catch块
被跳过的代码
echo "这行不会执行";
因为前面抛出异常
这行代码永远不会执行
捕获异常
} catch (PDOException $e) {捕获PDO相关异常
异常对象赋值给$e变量
输出错误信息
echo "<pre>"; echo "错误代码: " . $e->getCode() . "\n"; echo "错误信息: " . $e->getMessage(); echo "</pre>";
输出格式化错误信息
getCode()获取错误代码
getMessage()获取错误描述
使用<pre>标签保持格式
完整流程步骤:
开始异常捕获块
创建数据库连接
设置异常抛出模式
准备SQL查询语句
执行SQL语句(出错时抛出异常)
跳过后续正常代码
捕获抛出的异常
输出详细的错误信息
三、三种模式对比
四、使用建议与注意事项
模式选择建议:
生产环境推荐使用默认模式,配合完善的错误日志记录
开发调试阶段推荐使用异常模式,便于快速定位问题
警告模式适合过渡期或需要保留部分错误信息的场景
注意事项:
异常模式下要确保捕获PDOException而非基类Exception
默认模式下必须检查每个数据库操作的返回值
连接错误(如错误凭证)在任何模式下都会抛出异常
可通过构造参数或setAttribute()方法设置错误模式
最佳实践:
开发阶段使用异常模式+try-catch
记录详细的错误日志,包括errorInfo()内容
对用户显示友好错误信息,而非原始数据库错误
事务操作中异常模式能自动回滚未提交的事务
通过合理选择错误处理模式,可以更好地控制PDO在SQL错误发生时的行为,从而构建更健壮的数据库应用程序。