如何处理mysqli问题?像 mysqli_fetch_array() 这样的错误:参数 #1 必须是 mysqli_result 等类型

What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must be of type mysqli_result and such

提问人:siopaoman 提问时间:3/26/2014 最后编辑:Your Common Sensesiopaoman 更新时间:6/7/2023 访问量:74530

问:

在我的本地/开发环境中,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执行查询,结果是OK。

php mysqli 错误报告

评论


答:

186赞 Your Common Sense 3/26/2014 #1

TL;博士

  1. 始终在mysqli连接代码中,并始终检查PHP错误mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
  2. 始终将 SQL 查询中的每个 PHP 变量替换为问号,并使用预准备语句执行查询。这将有助于避免各种语法错误。

解释

有时您的 mysqli 代码会产生类似 或类似的错误。或者甚至没有任何错误,但查询的工作方式并不完全相同。这意味着您的查询无法执行。mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, boolean given...Call to a member function bind_param()...

每次查询失败时,MySQL都会显示一条错误消息来解释原因。在较旧的PHP版本中,这些错误不会转移到PHP中,你得到的只是上面提到的一个神秘的错误消息。因此,配置 PHP 和 mysqli 以向您报告 MySQL 错误非常重要。收到错误消息后,您将能够修复错误。

如何在mysqli中获取错误消息

首先,在所有环境中的mysqli connect之前始终有这一行:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

之后,所有MySQL错误都将转换为PHP异常。反过来,未捕获的异常会造成 PHP 致命错误。因此,如果出现MySQL错误,您将收到传统的PHP错误。这将立即使您意识到错误原因。堆栈跟踪将引导您到达发生错误的确切位置。

如何从PHP获取错误消息

在开发服务器上,确保错误显示在屏幕上,而在实时服务器上,检查错误日志。有关详细信息,请参阅我关于PHP错误报告的文章。

请注意,如果进行 AJAX 调用,请在开发服务器上打开 DevTools (F12),然后打开“网络”选项卡。然后发起您想要查看结果的请求,它将出现在“网络”选项卡中。单击它,然后单击“响应”选项卡。在那里,您将看到确切的输出。在实时服务器上,检查错误日志。

如何处理您收到的错误消息

首先,您必须找到问题查询。错误消息包含发生错误的确切位置的文件名和行号。对于简单的代码,这就足够了,但如果代码使用函数或类,则可能需要遵循堆栈跟踪来查找问题查询。

收到错误消息后,您必须阅读并理解它。如果不是居高临下,这听起来太明显了,但学习者经常忽略这样一个事实,即错误消息不仅仅是一个警报信号,而且它实际上包含了对问题的详细解释。您只需要阅读错误消息并解决问题即可。

  • 比如说,如果它说某个特定的表不存在,你必须检查拼写、拼写错误和字母大小写。此外,您必须确保您的PHP脚本连接到正确的数据库
  • 或者,如果它说 SQL 语法中有错误,那么你必须检查你的 SQL。问题点就在错误消息中引用的查询部分之前

如果您不理解错误消息,请尝试谷歌搜索。在浏览结果时,坚持解释错误的答案,而不是直截了当地给出解决方案。解决方案可能不适用于您的特定情况,但解释将帮助您了解问题并使您能够自行解决问题。

您还必须信任错误消息。如果它说标记数与绑定变量数不匹配,那么就是这样。缺席的表或列也是如此。如果可以选择,无论是你自己的错误还是错误的信息是错误的,请始终坚持前者。这听起来又是居高临下,但这个网站上的数百个问题证明这个建议非常有用。

基本调试

如果您的查询似乎不起作用,可能是由以下四个原因引起的:

  1. 执行过程中出现错误。上面已经解释过了。
  2. 由于程序逻辑不正确,SQL 根本没有运行。添加临时调试输出,以确保代码到达执行查询的位置。
  3. SQL 已成功执行,但在错误的数据库中查看了结果。仔细检查
  4. 输入数据与数据库不匹配。以下是有关如何检查它的一些建议

评论

0赞 Your Common Sense 5/26/2020
@AdamWinter使用 @ 总是错误的,在这种特殊情况下是错误的十倍。程序的错误消息与身体的疼痛相同。它告诉你有什么不对劲,比如你的腿断了。而且你必须修复腿,而不仅仅是吃止痛药然后继续。同样在这里。PHP 告诉你没有你期望的变量。因此,您必须修复表单或其他内容,以使此变量可用。不仅仅是编写代码来规避错误。
2赞 Barkermn01 9/9/2020
在大多数情况下,我同意,但是我不同意“你的常识”,“不仅仅是编写代码来规避错误”你认为尝试什么......catch 确实如此,它规避了错误以防止代码库以不受控制的方式退出,一些你无法在代码中修复的错误,例如 DB 服务器已经消失了,你只需要管理错误并规避错误即可产生有效的结果。
4赞 Your Common Sense 9/9/2020
@Barkermn01这是你的一个适当问题,但你从中得出了错误的结论。当然,您的应用程序应该产生一个有效的结果(如果出现“Mysql has gone away”错误,则该结果应为通用的 500 错误页面)。但你必须明白,这样一个有效的结果不是你的数据库代码所关心的问题。与数据库相关的代码应与数据库一起使用。而显示错误页面应该是不同代码的关注点。看这里: phpdelusions.net/articles/error_reporting
1赞 ToolmakerSteve 7/10/2021
“未捕获的异常反过来又会导致 PHP 致命错误”在 PRODUCTION 服务器上引起致命错误(对于 mysql 错误)是个好主意吗?在一些情况下,错误是否表明您的脚本应该处理的问题,并尽可能地继续;例如,通知用户您现在不能向他们提供该信息,同时提醒操作员进行调查?编辑我明白了,哪里需要你试试..捕获MySQL错误(您已转换为PHP错误)。
1赞 Your Common Sense 7/22/2022
@ToolmakerSteve你肯定指的是错误处理程序,而不是尝试捕获