如何处理 mysqli 问题? mysqli_get_array()之类的错误: 参数 # 1必须是 mysqli_result 类型的

在我的本地/开发环境中,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。

67612 次浏览

DR

  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 连接 所有之前,请始终使用以下代码行:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

之后,所有 MySQL 错误将被转移到 PHP 异常中。一个未捕获的异常反过来会导致一个 PHP 致命错误。因此,在出现 MySQL 错误的情况下,您将得到一个传统的 PHP 错误。这将立即让您意识到错误的原因。堆栈跟踪将引导您到错误发生的确切位置。

如何从 PHP 获得错误消息

以下是我关于 PHP 错误报告的文章的要点: 在开发服务器和活动服务器上报告错误必须不同。在开发服务器上,将错误显示在屏幕上是很方便的,但是在实时服务器上,必须记录错误消息,以便稍后在错误日志中找到它们。

因此,必须将相应的配置选项设置为以下值:

  • 在开发服务器上

  • error_reporting应设置为 E_ALL值;

  • log_errors应该设置为1(在开发 PC 上拥有日志也很方便)

  • display_errors应设置为1

  • 在生产服务器上

  • error_reporting应设置为 E_ALL值;

  • log_errors应设置为1

  • display_errors应设置为0

之后,当 MySQL 查询失败时,您将得到一个解释原因的 PHP 错误。在活动服务器上,为了得到错误消息,您必须检查错误日志。

如何实际使用它

只要删除任何手动检查错误的代码 ,所有这些 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 已经可以用正确的方式来报告错误了。

附注:
有时没有错误,但也没有结果。那就是 数据库中没有符合条件的数据。在这种情况下,你必须承认这个事实,即使你可以发誓数据和标准是正确的。他们不是。你得再检查一遍。

我有一篇文章可以帮助解决这个问题,如何调试数据库交互 。虽然它是为 PDO 编写的,但原理是相同的。只要按照这些说明一步一步地,要么解决了你的问题,要么对堆栈溢出有了一个可以回答的问题。