PHP Exception Handling - ErrorException

PHP Exception Handling – PDOException

Moving along through our in-depth PHP Exception Handling series, today we’ll be going over the PDOException. PHP Data Objects (or PDO) are a collection of APIs and interfaces that attempt to streamline and consolidate the various ways databases can be accessed and manipulated into a singular package. Thus, the PDOException is thrown anytime something goes wrong while using the PDO class, or related extensions.

In this article we’ll examine the PDOException by first looking at where it resides in the overall PHP Exception Hierarchy, then we’ll take a closer look at some fully functional code that will illustrate the basics of using PDO for database manipulation, and how that might lead to PDOExceptions, so let’s get to it!

The Technical Rundown

All PHP errors implement the Throwable interface, or are extended from another inherited class therein. The full exception hierarchy of this error is:

Full Code Sample

Below is the full code sample we’ll be using in this article. Feel free to use any or all of the code if you wish to follow along.

When Should You Use It?

As stated by the official documentation, the PDOException should never be directly thrown by your own code. Instead, it is thrown by the various PDO extensions whenever an error occurs while handling a database connection or query. To understand what this means, let’s first take a look at how PDO works, and why it might be better than “traditional” database handling in PHP.

At the most basic level, PDO is merely an abstraction layer between your PHP code and the underlying database your code is accessing. The beauty of this abstraction is that your code can be written, for the most part, in a database-independent manner. Connecting to a database, performing a query, retrieving the results, and other common tasks are all performed identically — using the same objects and methods — within PDO. Thus, if your application needs to transition from, say, MySQL to PostgreSQL, only a few minor adjustments will need to be made to keep most data-access code functional.

Another big advantage to PDO is its built-in support for data binding techniques. Data binding effectively allows your application code to automatically synchronize local data to its database source objects, and vice versa. When a change is made client-side, such as a user altering a value, a data binding can automatically update that matching value in the database, with (relatively) little effort on the part of the developer to make this happen.

There are many other advantages of PDO, but, for now, let’s jump into the example code to see how it works. For this setup we’re running MySQL 5.7 with the sakila sample database for testing purposes. Our basic goal is to use the PDO_MYSQL driver to allow us to connect to a MySQL database via PDO, just as we would with any of the other PDO-supported database types.

To simplify the process of establishing a PDO connection and execute some queries, we’ve created a basic Connector helper class:

The constructor accepts most of the connection-based parameters and creates a new PDO instance, which automatically attempts to connect to the specified data source. executeQuery(string $query) prepares and then executes the passed $query string, while fetchResults(int $returnType = PDO::FETCH_OBJ) attempts to fetch the results of the previously provided statement, if applicable. It’s worth noting that the fetch($fetch_style, ...) method’s first parameter determines how the retrieved data is formatted before being returned. There are tons of different options here, but we’ve opted for the FETCH_OBJ mode as default, which returns an anonymous class containing a field for each column and value. However, this is where data binding can be easily implemented. For example, PDO::FETCH_CLASS can be used to automatically create a new instance of a specified PHP class, mapping the retrieved values to their respective properties within the class definition. Pretty handy!

Anyway, we don’t need anything that fancy right now, so let’s test out our Connector class by trying to fetch a handful of actors from the sakila sample database:

Everything looks good, so executing the outputActors() function works as intended, outputting the first alphabetical actors in the table:

However, let’s see what happens if we try a connection with an invalid password:

Unsurprisingly, this throws a new PDOException, indicating that database access was denied:

Similarly, here we have a small typo in the name of our database, so let’s see what happens when we try to connect to the askila database to collect some city info:

Once again, a PDOException is thrown that indicates the particular problem:

Check out the Airbrake-PHP library, designed to quickly and easily integrate into any PHP project, giving you and your team access to real-time error monitoring and reporting throughout your application’s entire life cycle. With automatic, instantaneous error and exception notifications at your fingertips, you’ll be constantly aware of your application’s health, including any issues that may arise. Best of all, with Airbrake’s robust web dashboard cataloging every error that occurs, you and your team can immediately dive into the exact details of what went wrong, making it easy to quickly recognize and resolve problems.