mysqli_stmt_get_result 和 mysqli_fetch_all 不兼容?

Posted

技术标签:

【中文标题】mysqli_stmt_get_result 和 mysqli_fetch_all 不兼容?【英文标题】:mysqli_stmt_get_result and mysqli_fetch_all incompatible? 【发布时间】:2015-04-22 05:29:15 【问题描述】:

我正在尝试绑定参数(出于安全考虑),然后将结果放入数组中,因此我创建了如下代码。问题是它不起作用:$arr 为空。 (顺便说一句,我知道getList 中的查询有效。)

if ($stmt = mysqli_prepare($con, "call getList(?)")) 
    mysqli_stmt_bind_param($stmt, 's', $userInputSearch);
    mysqli_stmt_execute($stmt);
    $result = mysqli_stmt_get_result($stmt);

    $arr = mysqli_fetch_all($result, MYSQLI_ASSOC);
    $jsonArr = json_encode($arr);
    echo $jsonArr;

请注意,在使用 mysqli_query() 时,我必须使用 mysqli_fetch_all

在mysqli_fetch_all 参考上,我发现了这条评论:

另外,mysqli_fetch_all 仅适用于缓冲结果集,它们是 mysqli_query 的默认值。 MYSQLI_USE_RESULT 将在 5.3.4+ 但是,以这种方式使用它没有什么意义,具体化无缓冲集。在这种情况下,选择 STORE_RESULT,然后 fetch_all 不会复制数据,而是引用它,因为它是存储的 已经在 mysqlnd 中了。

我发现准备好的语句返回未缓冲的结果,所以我尝试使用 $result = mysqli_stmt_store_result($stmt) 而不是 $result = mysqli_stmt_get_result($stmt); 但这没有帮助。

这让我并没有完全不知所措——我知道我可以循环加载数据,一次加载一行,但我真的不想在 php 中循环只是为了做一些简单的事情,比如得到一个来自准备好的语句的数组。有没有办法将结果集作为一个对象来获取和处理?

【问题讨论】:

如果没记错的话,您必须始终使用 _stmt_ 函数,包括 mysqli_stmt_preparestmt_init 才能正常工作。 这是一个很好的例子,说明随着新特性的添加,MySQLi API 变得多么失控。文档清楚地说您可以使用来自mysqli_store_result() 的对象,但不要引用mysqli_stmt_store_result()。我喜欢这个问题。 【参考方案1】:

我刚刚重读了文档...

我现在无法测试mysql。

但只是猜测:

mysqli_fetch_all (mysqli_result $result ...

参数 result 仅限程序样式:结果集标识符 由 mysqli_query()、mysqli_store_result() 或 mysqli_use_result()。

我想强调所有函数 mysqli_query(), mysqli_store_result() mysqli_use_result() 属于 mysqli 类,而不是 stmt 并且它们返回类型 mysqli_result

但您正在尝试使用mysqli_stmt_get_result($stmt);

mysqli_result mysqli_stmt_get_result (mysqli_stmt $stmt) ...

返回值 失败时返回结果集或 FALSE。

所以这个函数返回类型resultset不是mysqli_result

因此您必须更改代码以不使用 mysqli_stmt

所以改变:

if ($stmt = mysqli_prepare($con, "call getList(?)")) 
    mysqli_stmt_bind_param($stmt, 's', $userInputSearch);
    mysqli_stmt_execute($stmt);

$result = mysqli_query ( $con , "call getList(".mysqli_real_escape_string($userInputSearch).")" );

,或 只需更改您的线路:

$arr = mysqli_fetch_all($result, MYSQLI_ASSOC);

$arr = array()
 while ($row = $result->fetch_array())
        
            arr[] = $row ;
        

如有错误请见谅,目前无法跟踪调试,希望对您有所帮助。

【讨论】:

来自 OP 的问题:“这让我并没有完全不知所措——我知道我可以循环一次加载一行数据,但 我真的不想必须在 PHP 中循环只是为了做一些简单的事情,比如从准备好的语句中获取一个数组。” 谢谢@KimAlexander。但是,在存储过程中处理转义字符串可能需要更多代码,所以我想我必须循环。虽然很伤心,但我想你得到了你付出的代价。也许我想要的可以在 ASP 中完成。 我认为新变体调用存储过程没有任何问题。它几乎和你以前的一样。这个mysqli_real_escape_string 只是清理值并为查询做准备。而且我无法理解由于这个原因在 asp 和 php 之间切换的逻辑。但你可以为所欲为。无论如何祝你好运:-) 我不打算换。我只是在沉思。

以上是关于mysqli_stmt_get_result 和 mysqli_fetch_all 不兼容?的主要内容,如果未能解决你的问题,请参考以下文章

第三十一节:扫盲并发和并行同步和异步进程和线程阻塞和非阻塞响应和吞吐等

shell中$()和 ` `${}${!}${#}$[] 和$(()),[ ] 和(( ))和 [[ ]]

Java基础8---面向对象代码块和继承和this和super和重写和重载和final

Java基础8---面向对象代码块和继承和this和super和重写和重载和final

JS中some()和every()和join()和concat()和pop(),push(),shift(),unshfit()和map()和filter()

malloc和free,brk和sbrk和mmap和munmap的使用和关系以及内存分配的原理