Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

php

mysqli

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?

like image 741
David Gausmann Avatar asked Nov 21 '16 12:11

David Gausmann


People also ask

What is mysqli-> prepare?

The mysqli_prepare() function prepares an SQL statement for execution, you can use parameter markers ("?") in this query, specify values for them, and execute it later.

Which mysqli function returns the last error code from the last connection error?

The error / mysqli_error() function returns the last error description for the most recent function call, if any.

What will be the return value of Mysqli_query () function on error?

Return Values ¶Returns false on failure. For successful queries which produce a result set, such as SELECT, SHOW, DESCRIBE or EXPLAIN , mysqli_query() will return a mysqli_result object. For other successful queries, mysqli_query() will return true .


1 Answers

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.

like image 170
David Gausmann Avatar answered Oct 09 '22 06:10

David Gausmann