Php 如果PDO事务失败,如何重定向到页面?

Php 如果PDO事务失败,如何重定向到页面?,php,mysql,sql,pdo,Php,Mysql,Sql,Pdo,我需要重定向到一个单独的页面来显示错误。标题(“位置:errorpage.php?errorcode=11”);之后似乎不起作用 <?php $db = new PDO("mysql:host=localhost;dbname=mydbase;charset=utf8", "user", "password"); try { $db->beginTransaction(); $db->exec("SOME QUERY"); $db->commit(); } cat

我需要重定向到一个单独的页面来显示错误。标题(“位置:errorpage.php?errorcode=11”);之后似乎不起作用

<?php
$db = new PDO("mysql:host=localhost;dbname=mydbase;charset=utf8", "user", "password");
try {
$db->beginTransaction();

$db->exec("SOME QUERY");

$db->commit();
} 

catch(PDOException $ex) {
$db->rollBack();
//Something went wrong so I need to redirect
header("Location: errorpage.php?errorcode=11");
}
有点不寻常。它有抛出真实异常、发出PHP警告或保持沉默的模式

默认情况下为静默。这里发生的事情是,不会抛出任何异常,因为您没有将PDO配置为抛出异常。因此,不会输入
catch
块,也不会调用
header()
。设置
$db
对象以引发异常:

// Ensure PHP's native error handling is showing
// on screen (to catch problems with header() itself)
error_reporting(E_ALL);
// Always in development, disabled in production
ini_set('display_errors', 1);

$db = new PDO("mysql:host=localhost;dbname=mydbase;charset=utf8", "user", "password");

// Turn on exceptions for PDO so the try/catch is meaningful
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

try {
  $db->beginTransaction();
  $db->exec("SOME QUERY");
  $db->commit();
} 

catch(PDOException $ex) {
  $db->rollBack();
  //Something went wrong so I need to redirect
  header("Location: errorpage.php?errorcode=11");
  // Always make an explicit call to exit() after a redirection header.
  exit();
}
关于
PDO::exec()


我知道这是示例代码,但是
exec()
通常不是正确的使用方法。如果您正在执行DDL语句,事务将无法工作,因为MySQL不支持DDL,如果您正在对任何用户输入执行
INSERT/UPDATE/DELETE
之类的操作,则应该创建一个注入安全的预处理语句。

如果它不重定向,那么您可能在头之前输出。在打开
或添加
ob_start()后立即将错误报告添加到文件顶部就在
ob_start()的正下方。
可能会起作用,但充其量只是一种黑客行为。排序逻辑以防止输出是非常可取的;添加exit(),但首先添加$db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_异常);工作。我的代码完全相似,只是我使用了$db->exec(“锁表
mydbase
”);所以我必须在锁定表后添加异常。@styxtrooper我很高兴它对您有效
exec()
适用于
LOCK TABLE
语句,但除非其中有其他
INSERT/UPDATE/DELETE
,否则事务将没有多大用处。(我想你可能会这样做,否则你为什么要锁定它?)我将把关于exec()的部分留给未来的读者,尽管它适合你的锁表命令,非常感谢你的帮助。我会为将来的项目插入数据,将考虑准备()/ExcUTE()。非常感谢。