Php 如何使用mysqli\u multi\u查询识别导致错误的查询?
使用其他地方的示例,以便更好地捕获“隐藏”错误。虽然下面的代码将捕获并返回一个错误,但是否可以改进此代码以报告发生错误的查询 使用以下代码,输出为:Php 如何使用mysqli\u multi\u查询识别导致错误的查询?,php,mysqli,error-handling,mysqli-multi-query,multiple-select-query,Php,Mysqli,Error Handling,Mysqli Multi Query,Multiple Select Query,使用其他地方的示例,以便更好地捕获“隐藏”错误。虽然下面的代码将捕获并返回一个错误,但是否可以改进此代码以报告发生错误的查询 使用以下代码,输出为: 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 lin
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);
}
在do循环中,添加一个计数器,每个成功的mysqli\u next\u结果都会增加计数器。一旦mysqli_next_结果返回false,也输出计数器 为了回答我自己的问题,由于文档很差,这里有一个解决方案,希望能帮助其他人。缺少的是捕获第一个查询错误的方法。myqsqli_multi_查询的隐藏操作很难理解 现在检查$err数组中的条目
$q[1] = "SELECT * FROM orders WHERE location = 'IN' ORDER BY orderNum DESC LIMIT 20";
$q[2] = "SELECT * FROM inventory";
$ord = array();
$invent = array();
$err = array();
$c = 1;
if(mysqli_multi_query($link, implode(';', $q))) {
do {
// fetch results
if($result = mysqli_use_result($link))
while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
if(count($row) > 17)
$orders[] = $row;
elseif(count($row) == 6)
$inv[] = $row;
}
}
$c++;
if(!mysqli_more_results($link))
break;
if(!mysqli_next_result($link) || mysqli_errno($link)) {
// report error
$err[$c] = mysqli_error($link);
break;
}
} while(true);
mysqli_free_result($result);
}
else
$err[$c] = mysqli_error($link);
mysqli_close($link);
这里的方法不仅可以提高错误消息的质量,还可以改进处理结果集的方式
$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>"; // <pre> is for easier array reading
var_export($rows[$q_key]);
echo "</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>";
}
可以从工作代码中删除行-这纯粹是为了演示
如果要在此代码块之后运行任何重用变量的查询,请确保清除所有已使用的变量,以便剩余数据不会干扰。e、 g.$mysqli_error=null;//清除错误并重置$q;//重置数组指针
请根据您自己的判断,注意这个有点模糊的警告:
如果服务器上有大量处理,则不应使用mysqli_use_result
执行客户端,因为这将占用服务器和
防止其他线程更新数据来自的任何表
被带走
最后也是最重要的一点,出于安全原因,不要公开显示查询或查询错误信息-您不希望邪恶的人看到这种反馈。同样重要的是,始终保护您的查询免受注入黑客攻击。如果您的查询包含用户提供的数据,则在mysqli_multi_查询中使用数据之前,需要对数据进行过滤/清理。事实上,在处理用户输入时,我强烈建议不要使用mysqli_multi_查询,而是将其用于数据库交互,以获得更高级别的安全性
这适用于两个查询 如果错误在第一个查询中,那么对PHP的第一个查询的响应就是错误消息,而对于不会触发的第二个查询,则在第一个查询中会出现一条消息 如果错误在第二个中,则返回第一个的响应,第二个获取错误消息 我正在使用关联数组和尼克松数组元素[0]。 只有存在相关错误时,才会添加['Error']键 最后,我不是最好的PHPer,所以这取决于你修复什么是丑陋的
好评论。这不会捕获第一个查询中的错误。当然,您需要检查所有函数的返回值,这意味着第一个查询的mysqli_multi_query和mysqli_store_result,以及其余所有查询的mysqli_next_result。-向上投票。关于mysqli\u multi\u查询的文档很少。希望你也能把这篇文章发上去。关于mysqli\u multi\u查询的文档很少。希望你也能发布这个目的的count$row?无论如何,不要硬编码这个值?如果$result=mysqli\u使用\u result$link{也…多个\u查询在第一个错误时停止,对吗?它不会继续下一个查询?那么mysqli\u error$link是否会不起作用?@MarcoZen lol这是8年半以前的事了。在那个年龄,我没有使用{}在2020年,mysqli\u multi\u查询仍然没有被广泛使用。
$query_nbr=0;
if (mysqli_multi_query($link,$query ))
{
do
{
unset($field_info) ; $field_info = array() ;
unset($field_names) ; $field_names = array() ;
unset($values) ; $values = array(array()) ;
if ($result = mysqli_store_result($link))
{
$query_nbr += 1 ;
$rows_found = mysqli_num_rows($result);
$fields_returned = mysqli_num_fields($result);
$field_info = mysqli_fetch_fields($result);
$field_nbr=0;
foreach ($field_info as $fieldstuff)
{ $field_nbr +=1 ;
$field_names[$field_nbr] = $fieldstuff->name ;
}
$now = date("D M j G:i:s T Y") ;
if ($query_nbr == 1)
{
$result_vector1 = array('when'=>$now) ;
$result_vector1['nrows']=0;
$result_vector1['nrows']=$rows_found ;
$result_vector1['nfields']=$fields_returned ;
$result_vector1['field_names']=$field_names ;
}
else
{
$result_vector2 = array('when2'=>$now) ;
$result_vector2['nrows2']=0;
$result_vector2['nrows2']=$rows_found ;
$result_vector2['nfields2']=$fields_returned ;
$result_vector2['field_names2']=$field_names ;
}
$row_nbr=0 ;
while ($row = mysqli_fetch_array($result, MYSQLI_BOTH))
{
$row_nbr++ ;
for ($field_nbr=1;$field_nbr<=$fields_returned;$field_nbr++)
{
$values[$row_nbr][$field_names[$field_nbr]] =$row[$field_nbr-1] ;
}
}
mysqli_free_result($result) ;
unset($values[0]) ;
if ($query_nbr == 1)
{$result_vector1['values']=$values ;}
else
{$result_vector2['values2']=$values ;}
} // EO if ($result = mysqli_store_result($link))
} while (mysqli_more_results($link) && mysqli_next_result($link)) ;
} // EO if (mysqli_multi_query($link,$query ))
else
{
// This will be true if the 1st query failed
if ($query_nbr == 0)
{
$result_vector1['Error'] = "MySQL Error #: ".mysqli_errno($link).": ".mysqli_error($link) ;
$result_vector2['Error'] = "MySQL Error in first query." ;
}
} // EO MySQL
// Here we only made it through once, on the 2nd query
if ( $query_nbr == 1 && $nqueries == 2 && empty( $result_vector2 ) )
{
$result_vector2['Error'] = "MySQL Error #: ".mysqli_errno($link).": ".mysqli_error($link) ;
}