如何处理mysqli问题? mysqli_fetch_array():参数 #1 必须是 mysqli_result 类型
Posted
技术标签:
【中文标题】如何处理mysqli问题? mysqli_fetch_array():参数 #1 必须是 mysqli_result 类型【英文标题】:How to deal with mysqli problems? mysqli_fetch_array(): Argument #1 must be of type mysqli_result 【发布时间】:2014-03-26 13:27:38 【问题描述】:在我的本地/开发环境中,mysqli 查询执行正常。但是,当我将它上传到我的网络主机环境时,我收到了这个错误:
致命错误:在...中的非对象上调用成员函数 bind_param()
代码如下:
global $mysqli;
$stmt = $mysqli->prepare("SELECT id, description FROM tbl_page_answer_category WHERE cur_own_id = ?");
$stmt->bind_param('i', $cur_id);
$stmt->execute();
$stmt->bind_result($uid, $desc);
为了检查我的查询,我尝试通过控制面板phpMyAdmin 执行查询,结果正常。
【问题讨论】:
可能是您的 MySQL 用户缺乏执行SELECT
查询的权限。你检查了吗?
【参考方案1】:
TL;DR
-
在你的 mysqli 连接代码中总是有
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
。它会让 MySQL 告诉您实际的问题是什么,无论是查询、服务器、数据库还是其他问题。
始终用问号替换 SQL 查询中的每个 PHP 变量,并使用 prepared statement 执行查询。这将有助于避免各种语法错误。
说明
有时您的 MySQLi 代码会产生类似 mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, boolean given...
、Call to a member function bind_param()...
或类似的错误。甚至没有任何错误,但查询并不完全一样。这意味着您的查询未能执行。
每次查询失败时,MySQL 都会一条错误消息说明原因。不幸的是,默认情况下,此类错误不会传输到 PHP,您所得到的只是上面提到的神秘错误消息。因此,配置 PHP 和 MySQLi 向您报告 MySQL 错误非常重要。一旦您收到错误消息,修复它将是小菜一碟。
如何在 MySQLi 中获取错误信息
首先,在您的所有环境中连接 MySQLi 之前,请始终使用此行:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
之后,所有的 MySQL 错误都会转入 PHP 异常。反过来,未捕获的异常会导致 PHP 致命错误。因此,如果出现 MySQL 错误,您将得到一个常规的 PHP 错误。这将立即让您意识到错误原因。堆栈跟踪将引导您找到发生错误的确切位置。
不同环境下如何配置PHP
这是我在PHP error reporting 上的文章的要点: 在开发服务器和实时服务器上报告错误必须不同。在开发服务器上,在屏幕上显示错误很方便,但在实时服务器上,必须记录错误消息,以便稍后在错误日志中找到它们。
因此,您必须将相应的配置选项设置为以下值:
在开发服务器上
error_reporting
应设置为E_ALL
值;
log_errors
应该设置为 1(在开发 PC 上登录也很方便)
display_errors
应设置为 1
在生产服务器上
error_reporting
应设置为E_ALL
值;
log_errors
应设置为 1
display_errors
应设置为 0
如何实际使用它
只需删除所有手动检查错误的代码,所有那些or die()
、if ($result)
等。立即编写您的数据库交互代码:
$stmt = $this->con->prepare("INSERT INTO table(name, quantity) VALUES (?,?)");
$stmt->bind_param("si", $name, $quantity);
$stmt->execute();
同样,周围没有任何条件。如果发生错误,它将被视为代码中的任何其他错误。例如,在开发 PC 上,它只会出现在屏幕上,而在实时站点上,它将为程序员记录下来,而为了用户的方便,您可以使用错误处理程序(但这是一个不同的故事,与主题无关MySQLi,但您可以在上面链接的文章中了解它)。
如何处理收到的错误消息
首先你要定位问题查询。错误消息包含发生错误的确切位置的文件名和行号。对于简单的代码就足够了,但如果您的代码使用函数或类,您可能需要按照 堆栈跟踪 来定位问题查询。
收到错误信息后,您必须阅读并理解它。如果不是居高临下的话,这听起来太明显了,但学习者经常忽略这样一个事实,即错误消息不仅仅是一个警报信号,它实际上包含一个对问题的详细解释。您只需阅读错误消息并解决问题。
比如说,如果它说某个特定的表不存在,那么您必须检查拼写、拼写错误和字母大小写。您还必须确保您的 PHP 脚本连接到正确的数据库 或者,如果它说 SQL 语法有错误,那么您必须检查您的 SQL。问题点就在错误消息中引用的查询部分之前。如果您不理解错误消息,请尝试 google。并且在浏览结果时,坚持解释错误的答案,而不是直截了当地给出解决方案。解决方案可能不适用于您的特定情况,但解释将帮助您了解问题并让您能够自行解决问题。
您还必须信任错误消息。如果它说令牌的数量与绑定变量的数量不匹配,那么它是。缺少的表或列也是如此。如果可以选择,无论是您自己的错误还是错误信息的错误,请始终坚持前者。再一次听起来有点居高临下,但这个网站上的数百个问题证明这个建议非常有用。
在错误报告方面你永远不应该做的事情的列表
切勿使用错误抑制运算符 (@
)!它使程序员无法阅读错误消息,因此无法修复错误
请勿使用die()
或echo
或任何其他功能无条件在屏幕上打印错误消息。 PHP 可以自行报告错误,并根据环境以正确的方式执行 - 所以就交给 PHP 吧。
不要手动添加条件来测试查询结果(如if($result)
)。启用错误异常后,这种情况将毫无用处。
不要使用try..catch
运算符来回显错误消息。该运算符应该用于执行一些错误处理,例如事务回滚。但是千万不要仅仅用它来报告错误——正如我们在上面了解到的,PHP 已经可以做到这一点,而且是正确的。
附言 有时没有错误,但也没有结果。那么这意味着,数据库中没有符合您条件的数据。在这种情况下,您必须承认这一事实,即使您可以发誓数据和标准都是正确的。他们不是。您必须再次检查它们。
我有一篇文章可以帮助解决这个问题,How to debug database interactions。虽然是为PDO写的,但是原理是一样的。只需按照这些说明一步一步地解决您的问题或对 Stack Overflow 提出可回答的问题。
【讨论】:
@AdamWinter 使用 @ 总是错误的,在这种特殊情况下是十倍。给你的程序发送错误信息就像给你的身体带来痛苦一样。它告诉你出了点问题,比如你的腿断了。而且您必须修复腿,而不仅仅是服用止痛药并继续前进。同样在这里。 PHP 告诉您没有您期望的变量。因此,您必须修复表单或其他任何内容,以使此变量可用。不只是编写代码来规避错误。 在大多数情况下,我同意,但我不同意“你的常识”,“不仅仅是编写代码来规避错误”你认为 try...catch 做什么,它规避防止代码库以不受控制的方式退出的错误,您无法在代码中修复的一些错误 E.G DB 服务器已经消失,您只需要管理错误并规避错误以产生有效的结果。 @Barkermn01 这是您的适当关注,但您从中得出错误的结论。当然,您的应用程序应该产生一个有效的结果(如果出现“Mysql has gone away”错误应该是一个通用的 500 错误页面)。但是您必须了解,这样一个有效的结果与您的数据库代码无关。您的数据库相关代码应该与数据库一起使用。而显示错误页面应该是不同代码的关注点。见这里:phpdelusions.net/articles/error_reporting 我知道它只是像“但永远不要仅仅使用它来报告错误”之类的东西,它有点排除了完全客观的代码库,例如我的 MVC,如果我的模型遇到错误,他们需要处理错误然后把它扔回去,这样我的模型使用被包装的控制器可以处理错误并显示错误,在这种情况下,我使用它是一个 API,所以错误和所有跟踪信息都会发送到 API 调用,如果它来自我们的远程系统(来源验证),因为现在有很多 web 东西剂量 PHP 后端 REACT 或 Angular 前端 “未捕获的异常反过来会导致 PHP 致命错误” 在 PRODUCTION 服务器上导致致命错误是个好主意(对于 mysql 错误)?是不是在少数情况下,错误表明您的脚本应该处理一个问题,并尽可能继续;例如通知用户您现在不能向他们提供该信息,同时提醒操作员进行调查? 编辑 我明白了,你在需要的地方尝试..catch mysql 错误(你已经转换为 php 错误)。以上是关于如何处理mysqli问题? mysqli_fetch_array():参数 #1 必须是 mysqli_result 类型的主要内容,如果未能解决你的问题,请参考以下文章
如何处理mysqli问题? mysqli_fetch_array():参数 #1 必须是 mysqli_result 类型
如何处理mysqli问题? mysqli_fetch_array():参数 #1 必须是 mysqli_result 类型
如何处理mysqli问题? mysqli_fetch_array():参数 #1 必须是 mysqli_result 类型
如何处理mysqli问题? mysqli_fetch_array():参数 #1 必须是 mysqli_result 类型
如何处理mysqli问题? mysqli_fetch_array():参数 #1 必须是 mysqli_result 类型