gpt4 book ai didi

php - 如何使用 mysqli_multi_query 识别导致错误的查询?

转载 作者:行者123 更新时间:2023-12-04 22:36:02 24 4
gpt4 key购买 nike

使用 SO 上其他地方的示例来更好地捕获“隐藏”错误。虽然下面的代码将捕获并返回错误,但是否可以改进它以报告发生错误的查询?

使用下面的代码,输出是:

Columns: 18
Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FRO inventory' at line 1

正在测试的代码:

$query = "SELECT * FROM orders WHERE location = 'IN' ORDER BY orderNum DESC LIMIT 20;";
$query .= "SELECT * FRO inventory"; // With error
$ord = array();
$invent = array();

if(mysqli_multi_query($link, $query)) {
do {
// fetch results
if($result = mysqli_store_result($link)) {
echo 'Columns: ' . mysqli_field_count($link) . "<br>";
while($row = mysqli_fetch_assoc($result)) {
if(count($row) > 17)
$orders[] = $row;
elseif(count($row) == 6)
$inv[] = $row;
}
}
if(!mysqli_more_results($link))
break;
if(!mysqli_next_result($link)) {
// report error
echo 'Error: ' . mysqli_error($link);
break;
}
} while(true);
mysqli_free_result($result);
}

最佳答案

这种方法不仅可以提高错误消息的质量,还可以改进您处理结果集的方式。

$q["Orders"] = "SELECT * FROM orders WHERE location = 'IN' ORDER BY orderNum DESC LIMIT 20";
$q["Inventory"] = "SELECT * FRO inventory";

if (!$link = mysqli_connect("host", "user", "pass", "db")) {
echo "Failed to connect to MySQL: " , mysqli_connect_error();
} elseif (mysqli_multi_query($link, implode(';', $q))) {
do {
$q_key = key($q); // current query's key name (Orders or Inventory)
if ($result = mysqli_store_result($link)) { // if a result set... SELECTs do
while ($row = mysqli_fetch_assoc($result)) { // if one or more rows, iterate all
$rows[$q_key][] = $row;
}
mysqli_free_result($result);
echo "<div><pre>" . var_export($rows[$q_key], true) . "</pre></div>";
}
} while (next($q) && mysqli_more_results($link) && mysqli_next_result($link));
}
if ($mysqli_error = mysqli_error($link)) { // check & declare variable in same step to avoid duplicate func call
echo "<div style=\"color:red;\">Query Key = " , key($q) , ", Query = " , current($q) , ", Syntax Error = $mysqli_error</div>";
}

第一次查询时出错:如果您的第一个查询尝试访问指定数据库中不存在的表,例如:ordersXYZ数组 $rows不会存在,没有 var_export()将发生,您将看到此响应:

Query Key = Orders, Query = SELECT * FROM ordersXYZ WHERE location='IN' ORDER BY orderNum DESC LIMIT 20, Syntax Error = Table '[someDB].ordersXYZ' doesn't exist

第二次查询出错:如果您的第一个查询成功,但您的第二个查询尝试访问一个不存在的表,例如:inventory2
$rows["Orders"]将保存所需的行数据并且将是 var_export() '编辑,$row["Inventory"]将不存在,您将看到此响应:

Query Key = Inventory, Query = SELECT * FROM inventory2, Syntax Error = Table '[someDB].inventory2' doesn't exist

没有错误:如果两个查询都没有错误,您的 $rows数组将填充所需的数据和 var_export() 'ed,不会有错误响应。将查询到的数据保存在$rows中, 您可以从 $rows["Orders"] 访问您想要的内容和 $rows["Inventory"] .


注意事项:

  1. 您可能会注意到我同时进行了变量声明和条件检查,这使代码更加简洁,但一些开发人员更愿意避免这种情况。

  2. 因为我的方法使用 implode()elseif 上有一个分号行,请确保不要在查询中添加尾随分号。

  3. 这组查询总是返回一个结果集,因为所有都是 SELECT 查询,如果您有一个混合的查询集合 affect_rows ,您可能会在此链接 ( https://stackoverflow.com/a/22469722/2943403 ) 中找到一些有用的信息。

  4. mysqli_multi_query()一旦出现错误,将立即停止运行查询。如果您希望捕获“所有”错误,您会发现永远不会超过一个。

  5. 像 OP 的问题和解决方案那样编写条件断点是不可取的。虽然在其他情况下可以正确使用自定义断点,但对于这种情况,断点应位于 while() 内部。 do()的声明 block 。

  6. 返回零行的查询不会导致错误消息——它只是不会在 $rows 中创建任何子数组。因为while()不会进入循环。

  7. 通过使用 key()函数,OP 的 if/elseif可以避免对每个结果集行中的列进行计数的条件。这是更好的做法,因为在某些情况下,每次迭代都运行一个条件可能会变得昂贵。请注意,数组指针在 $q 内部被提前在每个 do() 的末尾迭代。这是您在 php 手册页上找不到的附加技术;它允许 key()按预期工作。

  8. 当然还有 <div><pre>var_export()...</pre></div>行可以从您的工作代码中删除——这纯粹是为了演示。

  9. 如果您要在此代码块之后运行任何更多的查询以重用变量,请务必清除所有使用的变量,以免残留数据干扰。例如$mysqli_error=null; // clear errors & reset($q); // reset array pointer .

  10. 自行决定注意这个有些模糊的警告:http://php.net/manual/en/mysqli.use-result.php :

One should not use mysqli_use_result() if a lot of processing on theclient side is performed, since this will tie up the server andprevent other threads from updating any tables from which the data isbeing fetched.

  1. 最后,也是最重要的,出于安全原因,不要公开显示查询或查询错误信息——您不希望不怀好意的人看到这种反馈。同样重要的是,始终保护您的查询免受注入(inject)攻击。如果您的查询包括用户提供的数据,您需要在使用数据之前过滤/清理数据至死 mysqli_multi_query() .事实上,在处理用户输入时,我非常强烈的建议是远离 mysqli_multi_query()并使用 mysqlipdo为您的数据库交互准备好的语句以获得更高级别的安全性。

关于php - 如何使用 mysqli_multi_query 识别导致错误的查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12232974/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com