PDO的ATTR_ERRMODE属性介绍

博客介绍了PDO可通过设置ATTR_ERRODE属性控制SQL执行出错时的行为,有PDO::ERRMODE_SILENT(静默模式)、PDO::ERRMODE_WARNING(报warning错误)、PDO::ERRMODE_EXCEPTION(抛出异常)三种值,并给出代码演示,还提醒不要手动抛出PDOException以免混淆。

PDO可以通过设置ATTR_ERRODE属性来控制sql执行出错时的行为表现,具体可以设置以下三个值:

PDO::ERRMODE_SILENT  静默模式,不会报错,只会设置PDO的 errorCode

​​​​​​​PDO::ERRMODE_WARNING  会报warning错误

​​​​​​​PDO::ERRMODE_EXCEPTION  抛出异常

下面来看代码演示:

1、静默模式

<?php
try {
	$pdo = new PDO('mysql:dbname=test;host=127.0.0.1', 'root', 'root', [
		PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
	]);	
} catch (PDOException $e) {
	exit('连接数据库失败:' . $e->getMessage());
}

$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);

$sql = "SELECT id FROM not_a_table LIMIT 1";

$rs = $pdo->query($sql);

var_dump($pdo->errorCode());
print_r($pdo->errorInfo());

执行结果:

string(5) "42S02"
Array
(
    [0] => 42S02
    [1] => 1146
    [2] => Table 'test.not_a_table' doesn't exist
)

------------------------------------------------------------------------------------------------------------------------------------------------------------------

2、warning模式

<?php

try {
	$pdo = new PDO('mysql:dbname=test;host=127.0.0.1', 'root', 'root', [
		PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
	]);	
} catch (PDOException $e) {
	exit('连接数据库失败:' . $e->getMessage());
}

$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
ini_set('display_errors', 'On');

$sql = "SELECT id FROM not_a_table LIMIT 1";

$rs = $pdo->query($sql);

var_dump($pdo->errorCode());
print_r($pdo->errorInfo());

执行结果:


Warning: PDO::query(): SQLSTATE[42S02]: Base table or view not found: 1146 Table 'test.not_a_table' doesn't exist in E:\project\slim\web\pdo.php on line 16
string(5) "42S02" Array ( [0] => 42S02 [1] => 1146 [2] => Table 'test.not_a_table' doesn't exist )

---------------------------------------------------------------------------------------------------------------------------------------------------------------------

3、抛出异常:

<?php

try {
	$pdo = new PDO('mysql:dbname=test;host=127.0.0.1', 'root', 'root', [
		PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
	]);	
} catch (PDOException $e) {
	exit('连接数据库失败:' . $e->getMessage());
}

$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$sql = "SELECT id FROM not_a_table LIMIT 1";

try {
	$rs = $pdo->query($sql);
} catch (PDOException $e) {
	echo 'sql执行出错:' . $e->getCode() . '###' . $e->getMessage() . "\n";
}

var_dump($pdo->errorCode());
print_r($pdo->errorInfo());

执行结果:


sql执行出错:42S02###SQLSTATE[42S02]: Base table or view not found: 1146 Table 'test.not_a_table' doesn't exist
string(5) "42S02"
Array
(
    [0] => 42S02
    [1] => 1146
    [2] => Table 'test.not_a_table' doesn't exist
)

由于PDO抛出的是PDOException,所以我们的代码中尽量不要自己手动抛出PDOException,以免混淆。

<think>好的,我需要帮助用户找到包含指定PDO属性设置的SQL查询示例。用户提到了几个属性ATTR_ERRMODE设置为ERRMODE_EXCEPTION,ATTR_DEFAULT_FETCH_MODE设置为FETCH_ASSOC,以及ATTR_EMULATE_PREPARES。首先,我得回忆一下PDO的相关知识。 首先,PDO连接数据库时需要设置DSN,也就是数据源名称,比如mysql:host=localhost;dbname=test等,这点我记得引用[3]里有提到。接下来,用户提到的属性设置,ATTR_ERRMODE设置为异常模式,这样出错时会抛出异常,引用[1]和引用[4]都提到了异常处理的重要性,特别是防止SQL注入的部分。然后,默认的获取模式设为FETCH_ASSOC,这样查询结果会以关联数组的形式返回,避免数字索引带来的混乱。还有模拟预处理语句的设置,ATTR_EMULATE_PREPARES,这个可能需要根据数据库支持情况来决定是否启用,比如MySQL有时候需要关闭模拟预处理以使用原生预处理,提高安全性。 接下来,我需要将这些属性整合到一个示例中。连接数据库时,使用new PDO并传递DSN、用户名、密码。然后在options数组中设置这些属性。例如,设置ERRMODE_EXCEPTION为错误处理模式,FETCH_ASSOC为默认获取模式,以及EMULATE_PREPARES为false。然后,在查询时,使用prepare和execute方法,这样能防止SQL注入,如引用[2]和引用[4]所强调的。最后,确保在示例中展示如何执行查询并获取结果,比如使用fetchAll()。 另外,需要注意关闭连接的方式,虽然用户没有特别提到,但引用[5]指出PDO对象置为null后连接可能未释放,所以显式地设置$pdo = null可能更可靠。最后,生成相关问题时要围绕PDO属性设置、错误处理、预处理语句的应用等,帮助用户进一步学习。</think>以下是包含指定PDO属性设置的SQL查询完整示例,结合了错误模式、获取模式和预处理配置: ```php <?php try { // 设置连接参数及PDO属性 $pdo = new PDO( 'mysql:host=localhost;dbname=test;charset=utf8mb4', 'username', 'password', [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // 启用异常错误处理[^1] PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // 默认返回关联数组[^2] PDO::ATTR_EMULATE_PREPARES => false // 禁用模拟预处理[^4] ] ); // 预处理SQL查询示例 $stmt = $pdo->prepare("SELECT * FROM users WHERE email = :email AND status = :status"); $stmt->execute([ ':email' => 'user@example.com', ':status' => 1 ]); // 获取结果集(关联数组格式) $results = $stmt->fetchAll(); print_r($results); } catch(PDOException $e) { die("数据库错误: " . $e->getMessage()); } // 显式关闭连接 $pdo = null; ?> ``` ### 关键配置说明: 1. **ATTR_ERRMODE**:设置为`ERRMODE_EXCEPTION`后,所有数据库操作错误都会抛出异常,避免静默失败[^1] 2. **ATTR_DEFAULT_FETCH_MODE**:`FETCH_ASSOC`使结果集自动以字段名为键的关联数组返回,避免数字索引混乱[^2] 3. **ATTR_EMULATE_PREPARES**:设为`false`强制使用数据库原生预处理,防止某些SQL注入变种攻击 ### 注意事项: - 字符集建议使用`utf8mb4`以支持完整Unicode[^3] - 参数绑定通过命名占位符`:param`实现,可防止SQL注入 - 关闭连接使用`$pdo = null`比依赖析构函数更可靠[^5]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值