php 如何处理mysqli问题?mysqli_fetch_array():参数#1必须为mysqli_result等类型

waxmsbnn  于 2023-02-18  发布在  PHP
关注(0)|答案(1)|浏览(169)

在我的本地/开发环境中,MySQLi查询执行正常。但是,当我将其上载到Web主机环境中时,出现以下错误:
致命错误:在非对象上调用成员函数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执行查询,结果正常。

qnzebej0

qnzebej01#

TL;DR

1.在你的mysqli连接代码中总是有mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); * 并且总是检查PHP错误 *。
1.始终用问号替换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,你得到的只是上面提到的一个神秘的错误消息。因此,配置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

之后,当MySQL查询失败时,你会得到一个解释原因的PHP错误。在一个实时服务器上,为了得到错误消息,你必须检查错误日志。
在 AJAX 调用的情况下,在开发服务器上打开DevTools(F12),然后打开Network选项卡。然后启动您想要看到的结果的请求,它将出现在Network选项卡中。单击它,然后单击Response选项卡。在那里您将看到确切的输出。在实时服务器上检查错误日志。

如何实际使用

只需删除任何手动检查错误的代码,所有这些or die()if ($result)try..catch等。只需立即编写数据库交互代码:

$stmt = $this->con->prepare("INSERT INTO table(name, quantity) VALUES (?,?)");
$stmt->bind_param("si", $name, $quantity);
$stmt->execute();

同样,**不带任何条件。如果发生错误,它将被视为代码中的任何其他错误。例如,在开发PC上,它将只显示在屏幕上,而在实时站点上,它将为程序员记录,而为了用户的方便,您可以使用错误处理程序(但这是一个不同的故事,这是MySQLi的主题,但你可能会读到上面链接的文章)。

如何处理收到的错误消息

首先你必须找到问题查询。错误消息包含 * 文件名和行号 *,确切的地方发生错误。对于简单的代码,这就足够了,但如果你的代码使用函数或类,你可能需要遵循 * 堆栈跟踪 * 来找到问题查询。
在看到错误信息后,你必须阅读并理解它。这听起来太明显了,但学习者往往忽略了一个事实,即错误信息不仅仅是一个警报信号,它实际上包含了对问题的详细解释。而你所需要的只是阅读错误信息并修复问题。

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

如果你不明白错误信息,试着谷歌一下。当浏览结果时,坚持回答“解释”错误,而不是直截了当地给予解决方案。解决方案可能不适用于你的特定情况,但解释将帮助你理解问题,并使你能够自己解决问题。
你还必须 * 信任 * 错误消息。如果它说标记的数量与绑定变量的数量不匹配,那么它就是 * 如此。同样的道理也适用于缺失的表或列。如果可以选择,无论是你自己的错误还是错误消息是错误的,总是坚持前者。这听起来有点居高临下,但这个网站上的数百个问题证明了这个建议非常有用。

在错误报告方面永远不应执行的操作的列表

  • 不要使用错误抑制操作符(@)!它会使程序员无法读取错误消息,因此无法修复错误
  • 不要使用die()echo或任何其他函数在屏幕上无条件地打印错误消息。PHP可以自己报告错误,并且根据环境以正确的方式报告错误-所以让PHP来处理吧。
  • 不要手动添加条件来测试查询结果(如if($result))。启用错误异常后,这样的条件将毫无用处。
  • 不要使用try..catch操作符来回显错误消息。这个操作符应该用来执行一些错误处理,比如事务回滚。但是永远不要只使用它来报告错误--正如我们在上面学到的,PHP已经可以用正确的方式来做这件事了。
    附言

有时候没有错误,但是也没有结果,那就意味着,* 数据库里没有符合你条件的数据 ,这种情况下你就得承认这个事实,哪怕你可以发誓数据和条件都是对的,都不是,你得再检查一遍。
我有一篇文章可以帮助解决这个问题,
How to debug database interactions *。虽然它是为PDO编写的,但原理是相同的。只需一步一步地遵循这些说明,要么解决您的问题,要么为堆栈溢出提供一个可回答的问题。

相关问题