PHP PDO异常

PHP PDO异常,php,mysql,exception,pdo,transactions,Php,Mysql,Exception,Pdo,Transactions,我有一个很长时间都无法解决的问题。我有一个像这样的简单DB类 class DB { private static $dbserver = "mysql:dbname=db;host=localhost"; private static $dbuser = "root"; private static $dbpass = ""; public static function connectDB() { @$dbh = new PDO(self:


我有一个很长时间都无法解决的问题。我有一个像这样的简单DB类

class DB {

    private static $dbserver = "mysql:dbname=db;host=localhost";
    private static $dbuser = "root";
    private static $dbpass = "";

    public static function connectDB() {

        @$dbh = new PDO(self::$dbserver, self::$dbuser, self::$dbpass);
        $dbh->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
        $dbh->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, 'SET NAMES utf8');

        return $dbh;
    }
以及一个服务类,其中包含在数据库中写入数据的方法。表的类型是InnoDB。服务类如下所示

function insert_data($data) {
    $error = NULL;
    try {
        $dbh = DB::connectDB();
        $dbh->beginTransaction();

        $query_insert_1 = 'INSERT INTO table (f1, f2, f3) VALUES (?,?,?)';
        $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $stmt = $dbh->prepare($query_insert_1);
        $stmt->execute(array($d1, $d2, $d3));

        $last_insert_id = $dbh->lastInsertId();

        $query_insert_2 = 'INSERT INTO table2 (f4, f5, f6) VALUES (?,?,?)';
        $stmt = $dbh->prepare($query_insert_2);
        $stmt->execute(array($last_insert_id, $d4, $d5));

        $dbh->commit();             
    }
    catch(Exception $e) {                       
        $dbh->rollback();
        $error = $e->getMessage();
    }
    $return = new Result($error ? 1 : 0, $error ? 0 : 1, $error ? $error : '', NULL);
    error_log(print_r($error,1));
    return $return;
}
只有在函数insert_data中将PDO::ATTR_ERRMODE设置为PDO::ERRMODE_Exception时,PDO才会引发异常。如果我在DB类中设置它,则不会引发异常。这种行为的原因是什么

当我在这个问题()的函数中设置常量时,我有一个抛出异常的解决方案

谢谢你的帮助

迈克尔

编辑: 我最初的代码如下

class CarService {

private $dbh;

function __construct($dbh) {
    $this->dbh = $dbh;
}

function insert_car($customer_id, $brand, $model) {
    $error = NULL;

    try {
        $this->dbh->beginTransaction();

        $query_insert_car = 'INSERT INTO fahrzeug (kunde_id, fabrikat, modell) VALUES (?,?,?)';

        $stmt = $this->dbh->prepare($query_insert_car);
        $stmt->execute(array($customer_id, $brand, $model));
        // Get the ID of the last inserted car
        $last_insert_id = $this->dbh->lastInsertId();
        // Create the entry of the corresponding car version
        $query_insert_car_version = 'INSERT INTO fahrzeugversion (fahrzeug_id, version, fabrikat, modell) VALUES (?,?,?,?)';
        $stmt = $this->dbh->prepare($query_insert_car_version);
        $stmt->execute(array($last_insert_id, 1, $brand, $model));

        $this->dbh->commit();               
    }
    catch(Exception $e) {                       
        $this->dbh->rollback();
        $error = $e->getMessage();
    }

    $return = new Result(1, 0, NULL, NULL);
error_log(print_r($error,1));
    return $return;
}
new_car.php

<?php

require_once('DB.php');
require_once('CarService.php');
require_once('Result.php');

$dbh = DB::connectDB();
$car_service = new CarService($dbh);

$result = new Result(1, 0, NULL, NULL);

if (isset($_POST['fabrikat']) && isset($_POST['modell'])) {
    $brand = trim($_POST['fabrikat']);
    $model = trim($_POST['modell']);

    $result = $car_service->insert_car(1, $brand, $model);          
}   
print_r(json_encode($result));
?>

DB.php

<?php

class DB {

    private static $dbserver = "mysql:dbname=db;host=localhost";
    private static $dbuser = "root";
    private static $dbpass = "";

    public static function connectDB() {

        $dbh = new PDO(self::$dbserver, self::$dbuser, self::$dbpass);
        $dbh->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
        $dbh->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, 'SET NAMES utf8');
        $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        return $dbh;
    }

}
?>

PDO::ERRMODE_EXCEPTION
属性添加到PDO连接过程中

public static function connectDB() {

    $dbh = new PDO(self::$dbserver, self::$dbuser, self::$dbpass);
    $dbh->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
    $dbh->setAttribute(\PDO::MYSQL_ATTR_INIT_COMMAND, 'SET NAMES utf8');
    $dbh->setAttribute(\PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    return $dbh;
}
在您关闭此连接之前,它将为所有使用此连接的设备设置

现在,您可以从设置它的任何其他位置删除它

注:

也许这只是对何时抛出异常的误解

当PDO::ATTR_ERRMODE设置为PDO::ERRMODE_时,将引发异常

但是:

如果
PDO::ATTR\u EMULATE\u PREPARES=fale
->prepare()
语句将查询发送到数据库进行编译,因此如果查询未编译,您将得到
->prepare()
引发的异常

现在,如果
PDO::ATTR\u EMULATE\u PREPARES=true
prepare语句的作用非常小。此时查询不会发布到数据库进行编译。查询将作为
->execute()
处理的一部分发送到数据库进行编译,与编译失败相关的任何抛出的执行选项都将由“-->execute()语句抛出


看起来您的其他一些代码正在将PDO::ERRMODE_EXCEPTION设置为另一个值


如果您费心编写一个只涉及您在此处发布的代码的独立工作示例,您将看到异常将被抛出。

只是一个猜测,但请尝试从$dbh分配中删除@。它会抑制错误消息。你好,我想这不是问题所在。如果我在MySQL语法中出错,例如字段名错误,那么如果我在DB classHello RiggsFolly中设置ERR_模式,则不会引发异常,执行此操作时不会引发异常。这是我的默认设置。因为我在try块中添加了PDO::ERRMODE_EXCEPTION属性,所以会抛出异常。然后还有其他问题。让我仔细看看嗯,实际上这不是一个好的过程。您的代码将要求您在每个方法中建立连接,并且您只希望在每个脚本中建立一次连接谢谢您的帮助。我已经解决了这个问题。我想这是我的XAMPP的问题。我已经卸载并安装了它,现在它可以工作了:-)