I have a custom error handler defined, which catches all exceptions and saves them to a log. Right now, if I have a syntax error in a mysqli query, such as a typo, the page completely stops loading at that point. No exception is thrown, so therefore the error handler isn't triggered and nothing is logged.
Is this normal? Is there a PHP setting that I should check to fix this so that any mysqli query errors throw exceptions?
(I don't want an exception thrown if a query returns 0 results - only if it errors out due to a typo or other error in the query structure)
Example query:
if($result=$db->query('SELECT bad_field_reference FROM table')){while($r=$result->fetch_assoc()){$data[]=$r;}}$result->free();
If I try to execute this query in PHPMyAdmin it will tell me that column bad_field_reference does not exist. If I try to execute it as part of my PHP script, the entire page stops loading at that point.
To clarify I was just doing some testing by looking at the page source. Apparently the rest of the page does load - however, when java is enabled certain items are hidden, then I use jquery to redisplay some content in an animated fashion. Those jquery scripts are not running, so the page appears to have stopped loading.
So - 2 questions now - how do I get PHP to 'catch' the error, and how do I get jquery to still run it's scripts?
Is this normal?
No.
Is there a PHP setting that I should check to fix this so that any mysqli query errors throw exceptions?
Yes.
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
However, not all the mysqli_* functions would raise a DB error, some of them raise regular PHP errors, like free()
does, and this part makes me wonder even more: I am also extremely curious, why do you handle exceptions only but leave PHP errors unhandled. Don't tell me you have error_reporting(0);
- do you? If so - I've no words.
Finally, I have suspicion that you have raw mysqli->query() scattered all over the code. Which means
- you are using no placeholders to build your queries - making SQL injection inevitable.
- your code is bloated and unreadable
You have to use an abstraction library that will put all the repeated code into class methods. See your query run with safeMysql:
$data = $db->getAll('SELECT bad_field_reference FROM table');
it require no horizontal scrolling to read it, it is safe, concise, error-proof and supports placeholders!
I figured out the solution to the 'locking up' part. In my code sample, I have the following format:
if(--query--){--do something--}free result.
This works fine when the query is syntactically correct. If the query fails, however, there is no result to free. That is what was erroring and causing the page to appear as if it wasn't loading. Once I moved the 'free result' within the brackets such as
if(--query--){--do something-- free result}
It worked fine and didn't cause any issues. It still doesn't trigger an exception if the query was wrong, but for now I'm fixing that by creating an quick script after queries such as:
if($db->error){handle error}