How to make mysqli throw exceptions using MYSQLI_R

2020-01-22 12:32发布

问题:

There is a function in mysqli, called mysqli_report(), which looks like a counterpart for PDO's setAttribute() method with its ERRMODE_* constants. The manual says:

MYSQLI_REPORT_STRICT Throw mysqli_sql_exception for errors instead of warnings

So, having PDO::ERRMODE_EXCEPTION in mind, i tried this code

mysqli_report(MYSQLI_REPORT_STRICT);
$mysqli->query("foo");

but, to my disappointment, it produced no exception nor warning at all.

So, here goes the question: is there a way to tell mysqli to throw exceptions without using MYSQLI_REPORT_ALL?

回答1:

After some research I've finally learned that the function's parameter is a bitmask, and one have to combine several values to get the desired result. The final combination is not overly logical, but it works as intended, throwing an exception on a query error while ignoring warnings.

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

will produce the desired result:

Fatal error: Uncaught exception 'mysqli_sql_exception' with message 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'foo' at line 1'



回答2:

That's not a bug, that's a feature. ;)

PHP does not report mysqli or PDO errors by default because that information is highly sensitive, displaying it to a user is a great way to learn how to inject malicious data.

MYSQLI_REPORT_ERROR tells it to turn on the errors and MYSQLI_REPORT_STRICT tells it to convert those errors into Exceptions. This will give you a full report of the error message, so never do this in production environments.

Using the Pipe symbol | allows you to set multiple constants in most of PHPs methods and functions. PDO, mysqli, filter_var, etc. all use the pipe to set multiple optional arguments of the same type, or a "bitwise disjunction of flags" to use the fancy term for it. The lazy person's array argument.