为什么 'mysqli_query()' 返回 null?我怎么能弄清楚呢?



在某些情况下,PHP 中名为mysqli_query的内置函数返回null。解释如何使用它的函数文档没有预见到这种行为,所以我试图深入研究 PHP 的源代码本身,发布在 GitHub 上,看看我是否可以弄清楚为什么有时mysqli_query返回null

查询本身似乎不是问题:我以两种不同的方式测试了相关的SQL查询:

  • 在MySQL服务器中手动执行它们。它们工作正常。
  • 在我创建的脚本中,其唯一目的是通过mysqli_query()测试查询。它们在此测试下工作,并且函数返回true

但是,在某些情况下,这些相同的查询会返回null。当函数开始运行时mysqli_query当此"返回null失败"发生时,mysqli链接对象存在。

因此,在 PHP 的 GitHub 存储库中,我找到了名为mysqli_nonapi.c的文件,并且在此文件的第 556 行中,似乎是内置的mysqli_query定义。查看其中的代码,它看起来像是执行基本检查,如果失败,则返回null。以下是上面链接的第一行:

/* {{{ proto mixed mysqli_query(object link, string query [,int resultmode]) */
PHP_FUNCTION(mysqli_query){ 
MY_MYSQL           *mysql;
zval               *mysql_link;
MYSQLI_RESOURCE    *mysqli_resource;
MYSQL_RES          *result = NULL;
char               *query = NULL;
size_t              query_len;
zend_long           resultmode = MYSQLI_STORE_RESULT;
if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os|l", &mysql_link, mysqli_link_class_entry, &query, &query_len, &resultmode) == FAILURE) {
return;
}
// [...]
}

尽管我有时使用C代码,但我对C只有一点了解。我知道它使用指针,我想那些名称以*开头的参数是指针。无论如何,我不确定如何解释这段代码,或者弄清楚它的内部流程如何影响 PHP 执行。

长话短说:我可以以某种方式假设,由于某种原因,函数中上面显示的初始检查失败了。但是,要找出原因,我需要首先了解这段代码。

恐怕我无法隔离问题以在生产环境之外触发错误,这对于详尽的测试非常有用。那么,我还剩下什么选择呢?我是否可以做些什么来调试该内部代码段,或者找出它在其中可能失败的原因?

我在 PHP5 和 PHP7 中都做了测试;它们都以相同的方式失败。

这在PHP中称为未定义的行为。它的大多数实例在 PHP 8 中已被根除,但在该版本之前,当您将错误的参数传递给内置函数时,该函数通常会抛出警告并返回 null(或 false(。

在很多情况下,根本没有发出警告!这种行为没有记录在每个页面上,因为这将是一团糟,并且根据定义,"未定义的行为"没有定义的行为。

这意味着像下面这样的代码不会引发警告,而只是返回null

//                                          V - string passed instead of a numerical value
var_dump(mysqli_query($mysqli, 'SELECT 1', 'foo'));

PHP对参数类型非常宽容,当你传递错误的类型时,它会尝试将其转换为正确的类型,但是当这是不可能的时,PHP 没有定义应该发生的行为。值得庆幸的是,在 PHP 8.0 中,99% 的情况都已修复此问题。

最新更新