请查看我的代码:
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
当前输出:
something else is wrong
错误
预期产出:
inserting fails
错误
something else is wrong
错误
好的,如果我编写的代码类似于(没有链接),那么预期的输出会发生:
$stm = $dbh->prepare("INSERT INTO mytable(id,token) values(NULL,$token)");
$stm->execute();
我想知道,何时可以链接这些PDO语句?
答案 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)
只能在prepare
或execute
方法中抛出异常。其中任何一个都将在$stm =
之前发生。换句话说,如果将抛出异常,则$stm
的赋值总是将被跳过,这意味着该变量不会被删除在catch
块中存在。因此,它只能评估为false
,并且实际上会产生关于未定义的通知。
答案 2 :(得分:1)
你没有得到预期输出的原因是你写的方式,只要你得到PDOException
,$stm
就永远不会成真。如果prepare
或execute
失败,则$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;
}
}