Skip to main content

Why is it important to understand how PHP matches a catch block?

Image: Pixabay
PHP allows you to have multiple catch blocks.  The manual says that when an exception occurs PHP will try to find the first matching exception block, but it isn't entirely clear on exactly how  PHP matches "catch" blocks when handling exceptions.

Why is it important to understand how PHP matches a catch block?

It really relates to the fact that you are able to extend the base "Exception" class in PHP to make your own classes.  Throwing exceptions that are specific is good practice because it allows you to write catch blocks that are focused on solving just one sort of problem at a time.  The SPL exceptions are a good example of hierarchical exception inheritance in case you're wanting to see some practical usage.

In PHP a catch block is a match for an exception if the exception class is either the same as or inherits from the class in the catch clause.

Here's a trivial example:

In this example I've set up an exception class that extends the base exception class.  I'm throwing an instance of this child exception.  If I didn't know that PHP will match it's parent class I would expect the message "Child exception" to be output.

In actual fact if you run this code (here) you will see that the message "Parent exception" is output because PHP has matched MyException with its parent class.

The PHP manual doesn't make this explicit or obvious when discussing catch blocks or exception inheritance but it's one of those things that's always handy to know.

This implies that when we're coding multiple catch blocks we should place the more general parent classes at the bottom of the list.  This prevents them from catching exceptions that are meant for their children.

I discuss this and other gotchas  in my study guide for the Zend certification exam.

Comments

Popular posts from this blog

Solving Doctrine - A new entity was found through the relationship

There are so many different problems that people have with the Doctrine error message: exception 'Doctrine\ORM\ORMInvalidArgumentException' with message 'A new entity was found through the relationship 'App\Lib\Domain\Datalayer\UnicodeLookups#lookupStatus' that was not configured to cascade persist operations for entity: Searching through the various online sources was a bit of a nightmare.  The best documentation I found was at  http://www.krueckeberg.org/  where there were a number of clearly explained examples of various associations. More useful information about association ownership was in the Doctrine manual , but I found a more succinct explanation in the answer to this question on StackOverflow . Now I understood better about associations and ownership and was able to identify exactly what sort I was using and the syntax that was required. I was implementing a uni-directional many to one relationship, which is supposedly one of the most simpl...

Grokking PHP monolog context into Elastic

An indexed and searchable centralized log is one of those tools that once you've had it you'll wonder how you managed without it.    I've experienced a couple of advantages to using a central log - debugging, monitoring performance, and catching unknown problems. Debugging Debugging becomes easier because instead of poking around grepping text logs on servers you're able to use a GUI to contrast and compare values between different time ranges. A ticket will often include sparse information about the problem and observed error, but if you know more or less when a problem occurred then you can check the logs of all your systems at that time. Problem behaviour in your application can occur as a result of the services you depend on.  A database fault will produce errors in your application, for example. If you log your database errors and your application errors in the same central platform then it's much more convenient to compare behaviour between...

Translating a bit of the idea behind domain driven design into code architecture

I've often participated in arguments discussions about whether thin models or thin controllers should be preferred.  The wisdom of a thin controller is that if you need to test your controller in isolation then you need to stub the dependencies of your request and response. It also violates the single responsibility principal because the controller could have multiple reasons to change.   Seemingly, the alternative is to settle on having fat models. This results in having domain logic right next to your persistence logic. If you ever want to change your persistence layer you're going to be in for a painful time. That's a bit of a cargo cult argument because honestly who does that, but it's also a violation of the single responsibility principal.   One way to decouple your domain logic from both persistence and controller is to use the "repository pattern".   Here we encapsulate domain logic into a data service. This layer deals exclusively with imple...