在某些情况下,称为mysqli_query的PHP内置函数返回null。功能文档没有预见到这种行为,因为它解释了如何使用它,所以我尝试深入研究PHP的源代码本身,张贴在GitHub上,看看我是否能够弄清楚为什么有时mysqli_query会返回null。
查询本身似乎并不是问题所在:我用两种不同的方式测试了相关的SQL查询:
mysqli_query()测试查询。它们在此测试下工作,函数返回true。但是,在某些情况下,相同的查询返回null。当mysqli函数开始运行时,当这个“返回null失败”发生时,mysqli_query链接对象就会存在。
因此,在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中进行了测试;它们都以同样的方式失败。
发布于 2021-09-22 10:36:02
这在PHP中称为未定义行为。它的大多数实例在PHP 8中已经消除,但是在该版本之前,当您向内置函数传递一个错误的参数时,该函数通常会抛出警告并返回null (或false)。
在很多情况下,根本没有发出任何警告!这一行为没有记录在每一页上,因为这将是一片混乱,而且根据定义,“未界定的行为”没有明确的行为。
这意味着像下面这样的代码不会抛出警告,只需返回null
// V - string passed instead of a numerical value
var_dump(mysqli_query($mysqli, 'SELECT 1', 'foo'));PHP对参数类型非常宽容,当您传递错误的类型时,它试图将它转换为适当的类型,但是当这不可能时,PHP就没有定义应该发生什么的行为。值得庆幸的是,在PHP8.0中,99%的情况已经解决了这个问题。
https://stackoverflow.com/questions/50346196
复制相似问题