为什么不执行()错误时返回true?

时间:2016-07-08 15:10:19

标签: php mysql pdo

请查看我的代码:

try {
    // db connection here
    $stm = $dbh->prepare("INSERT INTO mytable(id,token) values(NULL,$token)")->execute(); 

} catch(PDOException $e){
    if ( $stm ){
        echo 'inserting fails';
    } else {
        echo 'something else is wrong';
    }
}

-- `token` column is unique

当前输出:

  • 已成功插入行。
  • 它为{duplicate entry}和{SQL syntax}
  • 打印something else is wrong错误

预期产出:

  • 已成功插入行。
  • 为{duplicate entry}
  • 打印inserting fails错误
  • 它为{SQL syntax}
  • 打印something else is wrong错误

好的,如果我编写的代码类似于(没有链接),那么预期的输出会发生:

$stm = $dbh->prepare("INSERT INTO mytable(id,token) values(NULL,$token)");
$stm->execute(); 

我想知道,何时可以链接这些PDO语句?

4 个答案:

答案 0 :(得分:2)

阅读PDO文档http://php.net/manual/en/book.pdo.php并查看返回值。只能在返回对象时链接,例如语句或结果集。

执行(http://php.net/manual/en/pdostatement.execute.php)返回一个布尔值,而不是一个对象,所以我们知道它不能被链接。 Prepare(http://php.net/manual/en/pdo.prepare.php)返回一个语句对象,因此我们可以使用return语句链接另一个方法调用。

这样想:

$stmt = $dbh->prepare("..sql..");
$bool = $stmt->execute();

这可以转化为:

$bool = $dbh->prepare("..sql..")->execute();

从 - > prepare()返回的是$ stmt。

答案 1 :(得分:2)

只能在prepareexecute方法中抛出异常。其中任何一个都将在$stm =之前发生。换句话说,如果将抛出异常,则$stm的赋值总是将被跳过,这意味着该变量不会被删除在catch块中存在。因此,它只能评估为false,并且实际上会产生关于未定义的通知。

答案 2 :(得分:1)

你没有得到预期输出的原因是你写的方式,只要你得到PDOException$stm就永远不会成真。如果prepareexecute失败,则$stm将无法定义。

我原本以为您可以通过从execute块中删除对catch成功的检查来解决此问题,但我错了。在仍然链接方法的同时,无法获得预期的输出。

try {
   $success = $dbh->prepare("INSERT INTO mytable(id,token) values(NULL,$token)")->execute();
   if (!$success) {
       // This can never be reached. If your have set PDO::ERRMODE_EXCEPTION, then either
       // the query is successful and $success === true, or the prepare or the execute
       // failed, and an exception will be thrown 
       echo 'inserting fails';
   }
} catch(PDOException $e){
    echo 'something else is wrong';
}

答案 3 :(得分:0)

仅供记录。要回答那个人试图问的问题。

来自我的article on PDO的代码(也修复了SQL注入):

try {
    $dbh->prepare("INSERT INTO mytable(token) values(?)")->execute([$token]);
} catch (PDOException $e) {
    if ($e->getCode() == 1062) {
        // insert failed due to duplicate key error
        echo "duplicate token";
    } else {
        // insert failed due to any other error
        throw $e;
    }
}