Jump to content

Silencing fatal errors in PHP 5.6?


maxxd

Recommended Posts

Hey y'all.

I've inherited a code base written in 5.6 that was at the time pretty bad and has since been abused pretty terribly; for instance, my predecessors decided to add '@'s to silence errors on mysql_* function calls instead of actually fixing things.

However, there are no '@'s on the nested require statements that instantiate the same object multiple times inside other files. In production, this somehow works just fine - I get no errors displayed and no errors logged despite having error logging turned on in the php.ini and the fact that it's a freaking fatal error. However, in my docker setup I'm getting errors about declaring the same class twice, and I can't use the system enough to debug it.

So I have a thought about how I can get around it locally in my docker container, but that solution can present problems when it comes to keeping track of actual changes versus changes for local development because this project has included every file in git - including the vendor and node_modules directories, as well as compiled files because ... well, reasons. So if I make changes locally to a file that shouldn't matter on the server, it will matter and will probably break things.

 

TL;DR - is it even possible to suppress fatal errors in PHP? If so, how?

 

Again, I feel the need to state that the only reason I'm asking is to debug the code I've inherited so I can fix it properly.

Edited by maxxd
Link to comment
Share on other sites

To be clear, you're talking about ignoring errors in the sense that PHP continues execution after?
No: once the error has been raised, that's it. They can't be trapped with set_error_handler() either, although they can be detected with some register_shutdown_function() trickery.

Assuming production isn't running some hacked version of PHP, and assuming that everything is running properly to completion, that must mean there aren't any fatal errors. So there's some difference between there and your setup.

  • Thanks 1
Link to comment
Share on other sites

I don't think it is possible.  I can't see how the code would possibly work in production either if it's trying to declare a class twice.  Only thing I can think of is the problem was fixed but that fix didn't make it into the version you have.

One way to try and deal with it while still being able to track you changes reasonably well would be to create a branch that has all the changes needed just to get the application working.  Then create a new branch from that to do your debugging on.  When done you can diff the two branches.

 

Link to comment
Share on other sites

7 hours ago, requinix said:

No: once the error has been raised, that's it. They can't be trapped with set_error_handler() either

That's what I thought - honestly the whole thing is making me crazy.

7 hours ago, kicken said:

Only thing I can think of is the problem was fixed but that fix didn't make it into the version you have.

That is terrifyingly possible, actually... I need to check the code on the server itself.

7 hours ago, kicken said:

One way to try and deal with it while still being able to track you changes reasonably well would be to create a branch that has all the changes needed just to get the application working.  Then create a new branch from that to do your debugging on.

That's what I've done for the time being. Just gotta remember not to commit until after I've triple checked everything.

Thanks for the sanity check, y'all - nice to know I'm not going completely crazy. Or at least probably not, anyway.

Link to comment
Share on other sites

11 minutes ago, benanamen said:

Are you using and IDE? PhpStorm is pretty smart at telling you what is wrong with your code. There are additional plugins for PHP Mess Detector and SonarLint that would also be of benefit.

I'm using VSCode right now, and it's finding plenty of errors. I'm pretty sure PHP Mess Detector would just give up the ghost and do itself in out of despair.

Like I said, the code is old - unfortunately, it doesn't use namespaces or autoloading so reference and definition detection is spotty at best. It also includes HTML in strings put into a variable then output via a global function.

The sad thing is, it's not the worst code I've seen in my time. It is, however, the first that somehow seems to keep running even after fatal errors...

Link to comment
Share on other sites

Try wrapping the class definition in an if(true) { }, which will prevent PHP from optimizing away the declaration, and then logging a debug_backtrace() somewhere before the if. Locally you should see two traces while in production there should only be the one. Then you can compare the traces to see if that suggests anything.

Link to comment
Share on other sites

Not sure how much LOC you have, but I have found it much faster to just start clean when I encounter an old code base. It always takes longer to fix someone else's bad code than it does to start clean. Hopefully you have that option, or at least enough hair on your head to pull out with your frustrations.

If it is not some super secret app you could put it on a repo and we could have a "Fun With Refactoring" Friday night.

Edited by benanamen
Link to comment
Share on other sites

2 hours ago, requinix said:

Try wrapping the class definition in an if(true) { }, which will prevent PHP from optimizing away the declaration, and then logging a debug_backtrace() somewhere before the if. Locally you should see two traces while in production there should only be the one. Then you can compare the traces to see if that suggests anything.

Oh, I like that idea - I ended up wrapping the couple problematic objects I've come across in if(!class_exists()) calls, which should be fine in case it hits production. I hadn't thought about logging a debug_backtrace(), though.

 

34 minutes ago, benanamen said:

Not sure how much LOC you have, but I have found it much faster to just start clean when I encounter an old code base. It always takes longer to fix someone else's bad code than it does to start clean. Hopefully you have that option, or at least enough hair on your head to pull out with your frustrations.

If it is not some super secret app you could put it on a repo and we could have a "Fun With Refactoring" Friday night.

I wish, on all accounts. Unfortunately I only came on board about 5 months ago so I've not gathered enough clout yet to say "scrap it - it sucks". I feel like I'm getting there, though, and hopefully with what was already in motion and the ideas I'm bringing in on top of that this code won't be here long. And luckily, most of the hair I have left is grey by now so it's not a huge loss. Now my liver, on the other hand, is probably really pissed at me.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.