Under certain circumstances, the built-in function in PHP called mysqli_query
returns null
. Such behaviour is not foreseen by the function's documentation that explains how to use it, so I tried to dive in PHP's source code itself, posted on GitHub, to see if I can figure out why sometimes mysqli_query
returns null
.
The queries themselves doesn't seem to be the problem: I tested the relevant SQL queries in two different ways:
mysqli_query()
. They work under this test, and the function returns true
.However, under certain conditions, those same queries return null
. The mysqli
link object exists when mysqli_query
function starts running, when this "returning null
failure" happens.
So, looking in the PHP's GitHub repository, i found the file called mysqli_nonapi.c
and, in line 556 within this file, what seems to be the built-in mysqli_query
definition. Looking at the code within, it looks like it performs a basic check and, if it fails, it returns null
. Here are the first lines linked above:
/* {{{ 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;
}
// [...]
}
Even though I have used sometimes C code, I just know a little about C. I am aware that it uses pointers and I guess those parameters which name start with *
are pointers. Anyways, I am not sure on how to interpretate this piece of code, or figuring out how it's internal flow affects PHP execution.
Long story short: I can assume somehow, the initial check shown above within the function failed for some reason. But, to find out why, I need to understand that piece of code first.
I am afraid I cannot isolate the issue to trigger the error outside production environment, which would be very useful for exhaustive testing. So, what options do I have left? Is there something I can do to debug that internal piece of code, or otherwise, figuring out why it might be failing within?
I made the tests in both PHP5 and PHP7; it fails the same way in both of them.
This is called undefined behaviour in PHP. Most instances of it have been eradicated in PHP 8, but prior to that version when you passed a wrong parameter to a built-in function, that function would usually throw a warning and return null (or false).
There were a lot of circumstances when no warning was produced at all! This behaviour was not documented on each page as this would be a mess and by definition "undefined behaviour" has no defined behaviour.
This means that code like the following would throw no warning and simply return null
:
// V - string passed instead of a numerical value
var_dump(mysqli_query($mysqli, 'SELECT 1', 'foo'));
PHP was very forgiving with parameter types and when you passed the wrong type, it tried to convert it into the proper type, but when this was not possible then PHP had no defined behaviour of what should happen. Thankfully, this has been fixed in 99% of cases in PHP 8.0.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With