回滚()和beginTransaction()在我的PHP PDO中不起作用

回滚()和beginTransaction()在我的PHP PDO中不起作用,php,mysql,database,pdo,Php,Mysql,Database,Pdo,RollBack()和beginTransaction()在我的PHP PDO中不起作用,我的表类型是innoDB。在下面的代码中,我的$sql1是正确的,而我的$sql2是错误的(我将d添加到$last\u id只是为了使它出错)。但它仍然执行sql1,这意味着回滚无效。谢谢您的建议 <?php include 'connect.php'; // Get multiple input field's value try { // set the PDO error mode

RollBack()
beginTransaction()
在我的PHP PDO中不起作用,我的表类型是
innoDB
。在下面的代码中,我的
$sql1
是正确的,而我的
$sql2
是错误的(我将
d
添加到
$last\u id
只是为了使它出错)。但它仍然执行sql1,这意味着回滚无效。
谢谢您的建议

<?php

include 'connect.php';
// Get multiple input field's value



try {
   // set the PDO error mode to exception
  $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);


   // Starts our transaction
   $conn->beginTransaction();

   foreach ($_POST['phone'] as $value) {

       $sql1 = "INSERT INTO tbl_contact_info (type)
       VALUES ('$value')";    

       // use exec() because no results are returned
       $conn->exec($sql1);
       $last_id = $conn->lastInsertId();

       $sql2="INSERT INTO tbl_img (img_type)
       VALUES ('$dlast_id')";    

       $conn->exec($sql2);    

   }
   // Commits out queries
   $conn->commit();
   echo "New record created successfully";    

}

catch(PDOException $e)
   {
   // Something borked, undo the queries!!    
   $conn->rollBack();    

   echo $sql . "<br>" . $e->getMessage();
   }

$conn = null;
?>
首先(很抱歉这很明显,但我意识到并非每个人都清楚)SQL和PHP是不同的语言。MySQL服务器不会对PHP代码中触发的未定义变量通知做出反应


其次,通知不是例外,因此不能用try/catch语句捕获它们。(您当然可以编写一个自定义错误处理程序,它将在错误时抛出异常,但这里的情况似乎不是这样。)

这是怎么回事
$dlast\u id
不存在,但PHP只需传入一个空字符串,
插入tbl\u img(img\u type)值(“”)
是有效的语法。您可以添加约束,以防止空字符串:谢谢您的评论。实际上,我故意添加了“d”以使其出错并回滚,但它没有回滚并执行sql2.FrankerZ,现在我只是理解了您的评论,所以您可以进一步解释如何为我的上述代码添加约束吗?感谢Alvaro,我不太理解您的答案,因为我对编程技能有点缺乏了解。然而,我试图使sql2出错,但它没有回滚。关键的一点是,该问题与SQL或PDO无关。我建议你看看这一章。PHP核心是从2005年开始的,当时该语言根本没有异常,这意味着许多基本错误(如
$dlast\u id
而不是
$last\u id
)根本不会抛出异常,因此您无法尝试/捕获它。再次感谢Alvaro。现在我明白了。实际上,我的回滚工作正常。那么,有没有什么好的方法可以通过使用PHP而不用触摸来编辑数据库来防止这种空插入呢?@user9547961这取决于您到底想完成什么。我不会浪费精力在运行时检测像这样的输入错误:一旦您尝试它,该功能根本不起作用就会变得显而易见。只需确保您的开发框配置为显示所有错误。但你真的需要使用事先准备好的陈述。它不仅是security 101,而且未定义的变量将呈现
null
,因此简单的
notnull
列定义将完全避免插入。