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的问题。我已经卸载并安装了它,现在它可以工作了:-)