提问者:小点点

mysqli_fetch_assoc()需要成员函数bind_param()的参数/调用错误。 如何获取实际的mysql错误并修复它?


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


共1个答案

匿名用户

有时您的MySQLi代码会产生类似mysqli_fetch_assoc()期望参数...调用成员函数bind_param()...或类似的错误。 或者甚至没有任何错误,但查询的工作方式并不完全相同。 这意味着您的查询无法执行。

每次查询失败时,MySQL都会有一条错误消息说明原因。 不幸的是,默认情况下,这样的错误不会传输到PHP,您得到的只是上面提到的一条神秘的错误消息。 因此,配置PHP和MySQLi以向您报告MySQL错误是非常重要的。 而且一旦你得到错误信息,修复它将是小菜一碟。

首先,在您的所有环境中,在MySQLi连接之前,始终要有这一行:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

之后,所有MySQL错误都将被转移到PHP异常中。 未捕获的异常则会导致PHP致命错误。 因此,如果出现MySQL错误,您将得到一个常规PHP错误。 这将使您立即意识到错误原因。 堆栈跟踪将引导您找到发生错误的确切位置。

下面是我关于PHP错误报告的文章的要点:
在开发服务器和现场服务器上报告错误必须是不同的。 在开发服务器上,在屏幕上显示错误是很方便的,但是在实时服务器上,错误消息必须被记录下来,这样您以后就可以在错误日志中找到它们。

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

> 开发服务器上的

    • Error_Reporting应设置为E_ALL值;
    • log_errors应设置为1(在开发PC上也有日志是很方便的)
    • display_errors应设置为1

    在生产服务器上

    • Error_Reporting应设置为E_ALL值;
    • log_errors应设置为1
    • display_errors应设置为0

    只需删除任何手动检查错误的代码,所有那些或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。 并且问题点正好位于错误消息中引用的查询部分之前。

    如果你不理解错误信息,试着谷歌它。 并且在浏览结果时,坚持解释错误的答案,而不是直截了当地给出解决方案。 一个解决方案可能不起作用,在您的特定情况下,但解释将帮助您理解问题,并使您能够自己解决问题。

    您还必须信任错误消息。 如果它说标记的数量与绑定变量的数量不匹配,那么它就是这样。 对于不存在的表或列也是如此。 如果有选择,不管是你自己的错误还是错误信息是错误的,总是坚持前者。 这听起来又是一种居高临下的态度,但是这个网站上的数百个问题证明了这个建议是非常有用的。

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

    P.S.
    有时没有错误,但也没有结果。 那么这意味着,数据库中没有数据与您的标准相匹配。 在这种情况下你不得不承认这个事实,即使你可以发誓数据和标准都是对的。 他们不是。 你得再检查一遍。 我有一篇文章可以帮助这件事,如何调试数据库交互。 虽然是为PDO编写的,但原理是一样的。 只需按照此指导一步一步地进行,或者解决您的问题,或者有一个堆栈溢出的可回答的问题。