Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 为什么';t execute()在出错时返回true?_Php_Mysql_Pdo - Fatal编程技术网

Php 为什么';t execute()在出错时返回true?

Php 为什么';t execute()在出错时返回true?,php,mysql,pdo,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 'somethin

请看一下我的代码:

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
当前输出:

  • 该行已成功插入
  • 它打印出{replicate entry}和{SQL syntax}的
    其他错误
    错误
预期产出:

  • 该行已成功插入
  • 它为{replicate entry}打印
    插入失败
    错误
  • 它打印出{SQL语法}的
    其他错误
    错误

好的,如果我像下面这样编写代码(没有链接),那么会出现预期的输出:

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

我想知道,什么时候可以链接那些PDO语句?

阅读PDO文档并查看返回值。您只能在返回对象(如语句或结果集)时进行链接

Execute()返回一个布尔值,而不是一个对象,因此我们知道它不能被链接。 Prepare()返回一个statement对象,因此我们可以使用return语句链接另一个方法调用

你可以这样想:

$stmt = $dbh->prepare("..sql..");
$bool = $stmt->execute();
这可以转化为:

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

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

无法获得预期输出的原因是您编写它的方式,任何时候当您得到一个
异常时,
$stm
都不可能是真的。如果
准备
执行
失败,则
$stm
将被取消定义

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

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';
}

异常只能在
prepare
execute
方法中引发。这两种情况都将发生在
$stm=
之前。换句话说,如果要抛出异常,则始终会跳过对
$stm
的赋值,这意味着该变量在
catch
块中根本不存在。因此,它只能计算为false,并且实际上会生成一个关于未定义的通知。

仅用于记录。为了回答这个人想问的问题

来自my的代码(还修复了SQL注入):


这被称为“流畅的界面”,你可能想阅读/google这个,这样你就能更好地理解它们在PHP中是如何工作的,以及为什么它在你当前的代码中不起作用。真正的问题是,你为什么要这样做?@JayBlanchard所有那些“酷而奇特”的人都这么做了。谁不想做同样的“花式”代码呢如果你只是将变量粘贴到SQL中而不是绑定参数,为什么不直接使用
query
而不是链接
prepare
execute
?我知道,我知道@Rizier123 SMH:PWell说,年轻的绝地武士。我刚读了@deceze answer后意识到这是错误的
$stm
不会为false,这将不起作用。我忘了execute也会导致异常。
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;
    }
}