严格标准:mysqli_multi_query 出现 mysqli_next_result() 错误

Posted

技术标签:

【中文标题】严格标准:mysqli_multi_query 出现 mysqli_next_result() 错误【英文标题】:Strict Standards: mysqli_next_result() error with mysqli_multi_query 【发布时间】:2013-01-20 20:57:22 【问题描述】:

我曾尝试使用 multi_query,但不断弹出严格的标准消息。

$querystring = "INSERT INTO responses VALUES('1', '2', '3', '4'); INSERT INTO responses VALUES('1', '2', '3', '4')";

if (mysqli_multi_query($db, $querystring)) 
   do 
       if ($result = mysqli_store_result($db)) 
           //
       
    while (mysqli_next_result($db));

echo "end";

我得到的错误信息是:

严格标准:mysqli_next_result():没有下一个结果集。请调用 mysqli_more_results()/mysqli::more_results() 检查是否调用此函数/方法

我尝试添加和删除-;,但没有成功。

【问题讨论】:

“我已经尝试添加和删除”您是否也尝试过... hhmmmm。 idunno 添加检查 mysqli::more_results()? 这几乎是无用的警告。基本上它要求你编写更丑陋的代码。这个警告背后的原因是什么? 【参考方案1】:

虽然 pipodesign 纠正了 $querystring 中的错误并缓解了问题,但并未提供有关严格标准错误的实际解决方案。

我不同意 SirBT 的建议,没有必要从 DO WHILE 更改为 WHILE。

您收到的严格标准信息非常丰富。 要服从,请使用:

do while(mysqli_more_results($db) && mysqli_next_result($db));

然后,您无需在循环内编写条件退出或中断,因为 while 条件将在第一次出现错误时中断循环。 *注意,如果第一个查询有错误,do-while 之前的 if 语句将拒绝进入循环。

在您的示例中,您只运行 INSERT 查询,因此您不会收到任何要处理的结果集。如果要计算添加了多少行,请使用 mysqli_affected_rows()。

作为您问题的完整解决方案:

if(mysqli_multi_query($db,$querystring))
    do
        $cumulative_rows+=mysqli_affected_rows($db);
     while(mysqli_more_results($db) && mysqli_next_result($db));

if($error_mess=mysqli_error($db))echo "Error: $error_mess";
echo "Cumulative Affected Rows: $cumulative_rows";

输出:

 // if no errors
Cumulative Affected Rows: 2

// if error on second query
Error: [something]
Cumulative Affected Rows: 1

// if error on first query
Error: [something]
Cumulative Affected Rows: 0

后期编辑:

由于刚接触 mysqli 的人偶然发现这篇文章,我将提供一个通用但强大的 sn-p 来使用 multi_query() 处理有/没有结果集的查询,并添加一个功能来显示数组中的哪个查询正在处理...

经典的“IF()DO WHILE”语法

if(mysqli_multi_query($mysqli,implode(';',$queries)))
    do
        echo "<br><br>",key($queries),": ",current($queries);  // display key:value @ pointer
        if($result=mysqli_store_result($mysqli))   // if a result set
            while($rows=mysqli_fetch_assoc($result))
                echo "<br>Col = $rows["Col"]";
            
            mysqli_free_result($result);
        
        echo "<br>Rows = ",mysqli_affected_rows($mysqli); // acts like num_rows on SELECTs
     while(next($queries) && mysqli_more_results($mysqli) && mysqli_next_result($mysqli));

if($mysqli_error=mysqli_error($mysqli))
    echo "<br><br>",key($queries),": ",current($queries),"Syntax Error:<br>$mysqli_error";  // display array pointer key:value

//if you want to use the snippet again...
$mysqli_error=null; // clear variables
reset($queries); // reset pointer

重新发明的***“WHILE”语法(...适用于那些不喜欢测试后循环的人):

while((isset($multi_query) && (next($queries) && mysqli_more_results($mysqli) && mysqli_next_result($mysqli))) || (!isset($multi_query) && $multi_query=mysqli_multi_query($mysqli,implode(';',$queries))))
    echo "<br><br>",key($queries),": ",current($queries);  // display array pointer key:value
    if($result=mysqli_store_result($mysqli))
        while($rows=mysqli_fetch_assoc($result))
            echo "<br>Col = $rows["Col"]";
        
        mysqli_free_result($result);
    
    echo "<br>Rows = ",mysqli_affected_rows($mysqli); // acts like num_rows on SELECTs

if($mysqli_error=mysqli_error($mysqli))
    echo "<br><br>",key($queries),": ",current($queries),"Syntax Error:<br>$mysqli_error";  // display array pointer key:value

//if you want to use the snippet again...
$multi_query=$mysqli_error=null; // clear variables
reset($queries); // reset pointer

因此,给定以下查询的任一 sn-p 都将提供相同的输出:

查询数组:

$queries[]="SELECT * FROM `TEST`";
$queries[]="INSERT INTO `TEST` (Col) VALUES ('string1'),('string2')";
$queries[]="SELECT * FROM `TEST`";
$queries[]="DELETE FROM `TEST` WHERE Col LIKE 'string%'";

输出:

0: SELECT * FROM `TEST`
Rows = 0

1: INSERT INTO `TEST` (Col) VALUES ('string1'),('string2')
Rows = 2

2: SELECT * FROM `TEST`
Col = string1
Col = string2
Rows = 2

3: DELETE FROM `TEST` WHERE Col LIKE 'string%'
Rows = 2

根据您的需要修改我的 sn-ps。如果您发现错误,请发表评论。

【讨论】:

【参考方案2】:

您收到此警告的原因仅仅是因为您使用了 do...while 循环,该循环在运行命令块后评估条件。因此,当没有更多结果时,循环的内容会再运行一次,从而产生该警告。

使用while ($mysql-&gt;next_result())...do 循环应该可以解决这个问题。 (一般来说:在数据库编程中,像你一样使用测试后循环是非常少见的)

如果代码是诗,我想成为莎士比亚!

【讨论】:

【参考方案3】:

(代表 OP 发布答案)

已解决:

$querystring = "INSERT INTO responses VALUES('1', '2', '3', '4'); INSERT INTO responses    VALUES('1', '2', '3', '4')";

if (mysqli_multi_query($db, $querystring)) 
do 
   if (!mysqli_more_results($db)) 
    exit();
   
 while (mysqli_next_result($db));

echo "end";

【讨论】:

以上是关于严格标准:mysqli_multi_query 出现 mysqli_next_result() 错误的主要内容,如果未能解决你的问题,请参考以下文章

如果不使用 mysqli_multi_query,SQL 注入将无法工作

sql无法通过mysqli_multi_query执行

SQL——注入攻击——mysqli_multi_query()的使用

mysqli_multi_query数组问题

PHP mysqli_multi_query 在while循环中的事务

资管业重磅新规!央行明确“非标”界定标准 超预期严格!影响有多大?