【问题标题】:PHP not throwing error for multiple queriesPHP不会为多个查询抛出错误
【发布时间】:2020-01-23 06:31:53
【问题描述】:

我有一些 PHP 代码来执行多个查询,其中一个查询有错误。但是 PHP 没有检测到它。这是代码

        $updateCategoriesQ = "DELETE FROM category_products WHERE product = $id; INSERT INTO category_products (category, products) VALUES ";
        foreach ($product['categories'] as $key) {
            $updateCategoriesQ .= "(".mysqli_real_escape_string($connect, $key)."', $id), "; //error is here in the quote
        }
        $updateCategoriesQ = rtrim($updateCategoriesQ, ', ');
        o($updateCategoriesQ);

        $updateCategories = mysqli_multi_query($connect, $updateCategoriesQ);
        if($updateCategories){
            o('query ok'); //receives this output (wrapper function for echo)
        }

形成的查询是

DELETE FROM category_products WHERE product = 1; INSERT INTO category_products (category, products) VALUES (1', 1), (2', 1)

第二个查询有错误,但 PHP 说没问题。如果我在第一个查询(删除)中创建错误,那么它会抛出错误,但如果错误在第二个查询中则不会。这里有不同的捕获错误的方法吗?

【问题讨论】:

  • 您是否启用并正确配置了错误报告?检查 phpinfo() 输出以验证您的配置。
  • mysqli_multi_query() 只返回第一次查询成功。要获得第二个查询的结果,您必须调用 mysqli_next_result()
  • 我建议不要使用mysqli_multi_query()。收益甚微,这让事情变得更加复杂。
  • 另外,您不能将准备好的语句与多查询一起使用。这比使用mysqli_real_escape_string() 更好。
  • @Barmar 我听到了你的建议,但你能分享一个例子吗?我一直没能找到它。我看到了如何使用它的结果,但没有看到如何检查查询是否成功。

标签: php mysqli error-handling mysqli-multi-query


【解决方案1】:

mysqli_multi_query() 的文档说:

如果第一个语句失败,则返回 FALSE。要从其他语句中检索后续错误,您必须先调用 mysqli_next_result()

$updateCategories = mysqli_multi_query($connect, $updateCategoriesQ);
if($updateCategories){
    o('delete query ok');

    $insertCategories = mysqli_next_result($connect);
    if ($insertCategories) {
        o('insert query ok');
    } else {
        o('insert query failed: ' . mysqli_error($connect));
    }
} else {
    o('delete query failed: ' . mysqli_error($connect));
}

【讨论】:

  • 我没有得到任何输出
【解决方案2】:

好的,在@Barmar 和this answer 的帮助下,这是捕获后续查询错误的好方法。

        $updateCategories = mysqli_multi_query($connect, $updateCategoriesQ);
        if($updateCategories){
            do {
                mysqli_next_result($connect);
                $result = mysqli_store_result($connect);
                if (!$result) {
                   o(mysqli_error($connect));
                }
            } while (mysqli_more_results($connect));
        } else {
            o(mysqli_error($connect));
        }

【讨论】:

  • 你似乎错过了更好的答案:stackoverflow.com/a/58783101/1839439 你不应该使用变量输入执行mysqli_multi_query()
  • 我没有错过。我了解多查询的缺点和陷阱,我还是决定继续使用它。即使我不使用它,我也想要一个解决这个问题的方法。
【解决方案3】:

不要使用mysqli_multi_query()!只有在没有用户输入的情况下才能使用此查询,即使这样也确实很麻烦且没有必要。

改为使用准备好的语句。这是推荐且安全的方式。

// Add this before new mysqli() to enable error reporting
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

$stmtDel = $connect->prepare('DELETE FROM category_products WHERE product = ?');
$stmtDel->bind_param('s', $id);
$stmtDel->execute();

$stmtInsert = $connect->prepare('INSERT INTO category_products (category, products) VALUES(?, ?)');
$stmtInsert->bind_param('ss', $key, $id);
foreach ($product['categories'] as $key) {
    $stmtInsert->execute();
}

正如您在此处看到的,我有两个单独的查询,我多次执行第二个查询。这更快,更安全,并且会抛出所有错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-04
    • 1970-01-01
    • 2019-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-11
    相关资源
    最近更新 更多