Thursday 15 June 2017

php - $mysqli->prepare returns false, but $mysqli->error is an empty string



In my code, I execute several valid SQL statements. But one of statement was invalid ($mysqli->prepare returns false), but no error code was returned ($mysqli->error returns false).



Here an example of the code:




$mysqli = new mysqli('host', 'user', 'password', 'database');

// First query (valid)
if(($oStatement = $mysqli->prepare('SELECT column FROM table;')) === false)
throw new Exception('Error in statement: ' . $mysqli->error);

// ...

// Second query (invalid)
if(($oStatement = $mysqli->prepare('SELECT column_which_doesnt_exist FROM table;')) === false)

throw new Exception('Error in statement: ' . $mysqli->error);


Why doesn't it return the error message?


Answer



I've spent a while to find the error. I didn't find something here, so I post this Q&A-Answer:



$mysqli->error returned an empty string, because the destructor of reused variable $oStatement had reset the error text.



In the error case the second $mysqli->prepare returned false and has set the error text. Then the return value (false) will be assigned to $oStatement. $oStatement contains a mysqli statement object, whose destructor will be called as part of the assignment. The destructor is called without any errors and resets the error text.




The correct solution is either to use different variables for each statement or to reset the statement variable before each assignment:



$mysqli = new mysqli('host', 'user', 'password', 'database');

// First query (valid)
$oStatement = false;
if(($oStatement = $mysqli->prepare('SELECT column FROM table;')) === false)
throw new Exception('Error in statement: ' . $mysqli->error);


// ...

// Second query (invalid)
$oStatement = false;
if(($oStatement = $mysqli->prepare('SELECT column_which_doesnt_exist FROM table;')) === false)
throw new Exception('Error in statement: ' . $mysqli->error);


With this solution the error text is valid and can be thrown.


No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...