1

I switched to PHP 8.2 a couple weeks ago (from PHP 7.0.something), but I have issues with it thinking every minor error from mysqli is fatal and fails to run the "die" part. This is an except from my MySQL interface class (this is for development use) that I've tried to get to work properly with PHP 8:

public function query($query) {
    $result = mysqli_query($this->db_link,$query) or $this->error('Unable to execute query<br/>'.$query);

  return $result;
}

public function error($message) {
   echo '<div align="center"><span style="font-size:150%;color:#FF0000;>ERROR! </span><span>'.$message.'<br /><br />'.mysqli_errno($this->db_link).': '.mysqli_error($this->db_link).'</span></div>';
  }

If I happen to have a typo or other issue in the query, on PHP 7 and pretty much every older version for the past several years, this would correctly jump to the error part whenever there was the slightest issue with the query and tell me what I need to know to fix it.

PHP 8 on the other hand completely ignores the 'OR' part and instead throws "Fatal error: Uncaught mysqli_sql_exception" with a mess of an error message that does not help me much at all since it only has like 4 characters from the query, which really is not enough with dynamically built queries.

In this case I appear to have a typo somewhere in a rather chunky query (since it's dynamically built), but because PHP fails to run the 'OR' part I'm left with this error

Fatal error: Uncaught mysqli_sql_exception: 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 '`0','0','1'' at line 9 in D:\web\testbase\include\mysql.php:53 Stack trace: #0 D:\web\testbase\include\mysql.php(53): mysqli_query(Object(mysqli), 'INSERT\r\n ...') #1 D:\web\testbase\work.php(36): db->query('INSERT\r\n ...') #2 {main} thrown in D:\web\testbase\include\mysql.php on line 53

Does PHP 8 require a completely different format for the 'DO OR DIE' approach or why does it refuse to execute the second half of the statement? (Note: I'm trying to avoid using actual 'DIE' as much as possible)

Also why does PHP go "fatal" here when a MySQL error by no means is fatal to the PHP parser. Sure the query fails, but I write my code to deal with that (or so I thought).

Dharman
  • 30,962
  • 25
  • 85
  • 135
  • 3
    Why not just fix the SQL error? It's fatal in a sense that it's a bug that needs fixing. "every minor error from mysqli" There are no minor errors. An error is something that the programmer must fix. End of story. – Dharman Jan 29 '23 at 00:19
  • 2
    Also, unrelated, but from the error it seems your code is wide open to SQL injection. You really should stop using `mysqli_query` and start using mysqli prepared statements. – Dharman Jan 29 '23 at 00:22
  • 1
    `why does it refuse to execute the second half of the statement`...because mysqli error reporting is turned on by default now. This is a good thing - it brings it into line more with how the rest of PHP behaves when something goes wrong - i.e. reporting it so you can understand it, instead of silently falling over. See https://phpdelusions.net/mysqli#error_handling and then https://phpdelusions.net/articles/error_reporting for an excellent tutorial on how to handle errors in a sane way in PHP. – ADyson Jan 29 '23 at 00:43
  • ` does not help me much at all since it only has like 4 characters from the query, which really is not enough with dynamically built queries.`...there's nothing to stop you handling / trapping the error and echoing the SQL _as well_ as the actual error message. – ADyson Jan 29 '23 at 00:44
  • Just want to say I appreciate the responses and just want to clarify a couple things: – SteelRodent Jan 29 '23 at 00:55
  • @Dharman Obviously I want to fix the SQL, that's why I want it to give me a nicer error message. Also this code is not used online, at all, and presently not by anyone but me. But all data taken from forms/url etc. is properly escaped, type checked, and usually processed before it's allowed in my queries. – SteelRodent Jan 29 '23 at 01:08
  • @ADyson I'm not complaining that it throws an error. I want the errors. I just want them slightly easier to read which doesn't work when it skips the 'OR' part. Will read the linked articles tho. Thx – SteelRodent Jan 29 '23 at 01:08
  • 1
    Yeah, but what I am saying is that because of SQL injection you might be getting these errors. Don't justify SQL injection, just fix it with parameterized prepared statements. In terms of the message, the exception gives you a stack trace so you can pinpoint the exact place where it went wrong. – Dharman Jan 29 '23 at 01:14
  • 1
    `I just want them slightly easier to read which doesn't work when it skips the 'OR'`...it does, you just need to handle it slightly differently - like i said, you can `catch` the exception if you want, and log the full SQL string as well as the exception message. It's just a case of modernising your code and making it more consisent with the rest of PHP.The not-throwing-an-error-when-a-sql-error-occurs silliness is a hangover of PHP4 and the old obsolete `mysql_` library which `mysqli` replaced 20 years ago, but it perhaps tried to ape it a bit too closely (no doubt for continuity at the time) – ADyson Jan 29 '23 at 01:46
  • `is properly escaped, type checked, and usually processed before it's allowed in my queries`...none of those things can guarantee to provide security against injection attacks though, or even against possible accidental syntax errors in the query, in the robust way that prepared statements do. They're not hard to write...there's really no justification not to use them - it can only improve your code quality and reliability. – ADyson Jan 29 '23 at 01:50
  • `Also why does PHP go "fatal" here when a MySQL error by no means is fatal to the PHP parser`...you could say that about a lot of errors probably. But it's serious enough that your script might want to stop so you can see it, and it doesn't accidentally cause more trouble further down the line (due to incorrect data or whatever). There could easily be a ripple effect. Plus, really a SQL failure should be a "never" event once you're past the testing phase...if it occurs in a live system, it should be treated as a significant bug / problem, and needing fixing pretty quickly. – ADyson Jan 29 '23 at 01:53
  • 1
    @SteelRodent I understand your intentions. And I understand your local conditions (that look more like petty excuses). But you must understand they are all wrong. PHP is a language with bad heredity. You're right, for ages, "on PHP 7 and pretty much every older", PHP programmers did it ALL WRONG. Now the language grows, helping devs to go the right way. If you think of it, a database-related code should NEVER interact with a user, just like your code does. Want a nicer error message? Fine, make all error messages fine. Also make it configurable, so it can be shut or change in a single place – Your Common Sense Jan 29 '23 at 06:06
  • 1
    Great question though, we need a good canonical answer on it – Your Common Sense Jan 29 '23 at 06:08

0 Answers0