PDO 设置属性错误模式

PDO::setAttribute 在数据库句柄上设置一个属性。setAttribute 的描述是:

public bool PDO::setAttribute ( int $attribute , mixed $value )

PDO::ATTR_ERRMODE: 此属性用于错误报告。它可以具有以下值之一。

  • PDO::ERRMODE_SILENT:如果代码中未设置 ATTR_ERRMODE,则 ERRMODE_SILENT 是 ATTR_ERRMODE 属性的默认值。它设置错误代码。在静默模式下,如果 SQL 中存在错误,PDO 将不会抛出异常; PDO 不会发出任何警告; 它只会返回 false。PDO::ERRMODE_SILENT 的值为 0.脚本将运行而不会生成任何错误或警告。
  • PDO::ERRMODE_WARNING:该值引发 E_WARNING。在警告模式下,如果 SQL 中存在错误,PDO 将发出警告但脚本将继续运行。PDO::ERRMODE_WARNING 的值为 1.脚本将运行并生成有关错误的警告。
  • PDO::ERRMODE_EXCEPTION:此值抛出异常。在异常模式下,如果 SQL 中存在错误,PDO 将抛出异常并且脚本将停止运行。PDO::ERRMODE_EXCEPTION 的值为 2.脚本将停止执行生成引发异常的错误。

示例:现在我们将通过一些示例来查看属性 ATTR_ERRMODE 的各种值。为此,创建一个名为 learn_project_db 的数据库,并在其中插入一个名为 user_table 的表。以下 SQL 代码段可用于实现:

DROP DATABASE IF EXISTS `learn_project_db`;
CREATE DATABASE `learn_project_db`;
USE `learn_project_db`;
CREATE TABLE `user_table` (
  `user_email` varchar(50) PRIMARY KEY,
  `user_password` varchar(50) NOT NULL
);
INSERT INTO `user_table` (`user_email`, `user_password`) VALUES
('test1@example.com', '123'),
('test2@example.com', '1234'),
('test3@example.com', '12345');

首先,我们将检查如果我们不设置 ATTR_ERRMODE 会发生什么,我们将在 SQL 查询中出错。创建一个名为 default.php 的 PHP 文件,试试这个:

<?php
    $server = "localhost";
    $db_username = "root";
    $db_password = "";
    $db_name = "learn_project_db";
    $conn = new PDO("mysql:host=$server;dbname=$db_name",$db_username,$db_password);
    $sql_query = "SELECT * FROM wrong_user_table";
    $stmt = $conn->prepare($sql_query);
    $stmt->execute();
    $result_set = $stmt->fetchAll();
    var_dump($result_set);
    /*Get the current error mode of PDO*/
    $current_error_mode = $conn->getAttribute(PDO::ATTR_ERRMODE);
    echo "<br>";
    echo "Value of PDO::ATTR_ERRMODE: ".$current_error_mode; 
?>

请注意,查询中的表名是 wrong_user_table,该名称未在我们之前创建的数据库中定义。但是,由于我们没有设置 ATTR_ERRMODE,它将运行脚本而不会抛出任何异常或发出任何警告。它将输出一个空数组作为结果集。我们还应该注意到,PDO::ATTR_ERRMODE 的值是 0。

现在,我们将检查如果我们将 ATTR_ERRMODE 设置为 PDO::ERRMODE_WARNING 会发生什么,我们将在 SQL 查询中出错。创建一个名为 warning.php 的 PHP 文件,试试这个:

<?php
    $server = "localhost";
    $db_username = "root";
    $db_password = "";
    $db_name = "learn_project_db";
    $conn = new PDO("mysql:host=$server;dbname=$db_name",$db_username,$db_password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);    
    $sql_query = "SELECT * FROM wrong_user_table";
    $stmt = $conn->prepare($sql_query);
    $stmt->execute();
    $result_set = $stmt->fetchAll();
    var_dump($result_set);
    /*Get the current error mode of PDO*/
    $current_error_mode = $conn->getAttribute(PDO::ATTR_ERRMODE);
    echo "<br>";
    echo "Value of PDO::ATTR_ERRMODE: ".$current_error_mode; 
?>

warning.php 的输出是:

Warning: PDOStatement::execute(): SQLSTATE[42S02]: Base table or view not found: 1146 Table 'learn_project_db.wrong_user_table' doesn't exist in E:\xampp\htdocs\oop\db.php on line 10
array(0) { } 
Value of PDO::ATTR_ERRMODE: 1

这一次,当我们用 PDO::ERRMODE_WARNING 值设置 ATTR_ERRMODE 时,它将显示一条警告信息。该脚本成功运行并显示一个空数组作为输出,其值为 PDO::ATTR_ERRMODE 为 1。

最后,我们将检查如果我们将 ATTR_ERRMODE 设置为 PDO::ERRMODE_EXCEPTION 会发生什么,我们将在 SQL 查询中出错。创建一个名为 error.php 的 PHP 文件,试试这个:

<?php
    $server = "localhost";
    $db_username = "root";
    $db_password = "";
    $db_name = "learn_project_db";
    $conn = new PDO("mysql:host=$server;dbname=$db_name",$db_username,$db_password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);    
    $sql_query = "SELECT * FROM wrong_user_table";
    $stmt = $conn->prepare($sql_query);
    $stmt->execute();
    $result_set = $stmt->fetchAll();
    var_dump($result_set);
    /*Get the current error mode of PDO*/
    $current_error_mode = $conn->getAttribute(PDO::ATTR_ERRMODE);
    echo "<br>";
    echo "Value of PDO::ATTR_ERRMODE: ".$current_error_mode; 
?>

error.php 的输出是:

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42S02]: Base table or view not found: 1146 Table 'learn_project_db.wrong_user_table' doesn't exist' in E:\xampp\htdocs\oop\db.php:10 Stack trace: #0 E:\xampp\htdocs\oop\db.php(10): PDOStatement->execute() #1 {main} thrown in E:\xampp\htdocs\oop\db.php on line 10

这一次,当我们用 PDO::ERRMODE_EXCEPTION 值设置 ATTR_ERRMODE 时,它会抛出 PDOException,这会产生致命的错误。抛出异常后,脚本将停止执行。这是处理数据库查询相关错误的最常用方法。在大多数情况下,我们使用此值设置属性 ATTR_ERRMODE 来处理可能驻留在 SQL 查询中的任何异常。