Please wait

Understanding Exceptions

Applications don't always run smoothly. They will inevitably run errors. In these cases, you can use exceptions to help you handle problems gracefully.

Exceptions in PHP are like safety nets. When something goes wrong in your code, instead of letting it fall and crash, you can "throw" it into one of these nets. These nets, called "catch blocks", are specially set up to deal with these problems, allowing your code to either recover gracefully or let you know what went wrong. This way, you can handle unexpected issues in a clear and organized manner.

Before we learn how to catch exceptions, let's learn how to throw them and create custom exceptions.

Difference from Errors

You may be wondering, how are exceptions different from errors? Both errors and exceptions represent problems that can arise during code execution. However, they differ in their origins, how they're handled, and their underlying philosophies.

These are usually unanticipated issues that arise during script execution, like trying to access an undefined variable or calling an undefined function. They are typically serious problems that will halt the execution of your script. On the other hand, exceptions are more structured and are used for expected but irregular situations in an application. They have to be explicitly created.

With errors, there's not much flexibility in terms of categorizing different types of errors. Whereas exceptions can be extended to create custom exception types, allowing for more specific exception handling.

In essence, while both errors and exceptions pertain to problem handling in PHP, exceptions offer a more structured and object-oriented approach. They enable developers to anticipate and react to irregularities without necessarily considering them as catastrophic failures, as traditional errors might imply.

Throwing an Exception

What does it mean to throw an exception? Throwing an exception is like sounding an alarm when something unexpected happens in your code. Instead of continuing as if nothing's wrong, your program shouts, "Hey, there's a problem here!" and stops its usual process to deal with that problem.

Imagine you're at a vending machine. You put in money, select a snack, but nothing comes out. Now, the vending machine could just ignore this and move on, but that would leave you frustrated without a snack. Instead, it lights up an "Error" message or beeps to let you know something's wrong. This is similar to throwing an exception in coding - it's a way for the program to signal that it can't continue normally due to some issue.

In PHP, you throw an exception using the throw keyword followed by a new instance of the Exception class.

if (!$snack) {
  throw new Exception("The snack is not available!");
}

In this example, if the $snack variable doesn't have a value (maybe our virtual vending machine is out of that snack), the code will throw (or sound the alarm) an exception with the message "The snack is not available!".

PHP Exceptions

PHP offers a rich hierarchy of exception classes, allowing for more specific and nuanced error handling. The advantage of having specialized exception classes is that they allow developers to pinpoint and handle different types of issues in tailored ways.

Catching Exceptions

So far, the idea of catching exceptions has been mentioned. This is a topic we'll focus on in the next lesson. For now, we're just focused on throwing exceptions.

Here's a markdown table for some of the key exception classes in PHP:

markdown

Class NameDescription
ExceptionThe base class for all user-level exceptions. Most custom exceptions should extend this class.
ErrorExceptionRepresents errors that are used during PHP's script execution, often generated by the core of PHP itself.
LogicExceptionRepresents a logical error in the code. Its subclasses include errors like BadFunctionCallException.
RuntimeExceptionRepresents runtime errors that occur while executing a script.
InvalidArgumentExceptionThrown if a function receives an argument that is not valid.
LengthExceptionThrown when a length-related issue occurs, e.g., if an array is too long.
OutOfBoundsExceptionThrown if a value is not within an expected range (e.g., accessing an out-of-bounds array element).
OverflowExceptionThrown when you add an element into a full container, like adding to a full array.
UnderflowExceptionThrown when you try to remove an element from an empty container, like popping an element from an empty stack.
RangeExceptionRepresents errors that occur when using a value outside its valid range.
DomainExceptionRepresents exceptions related to mathematical operations.
UnexpectedValueExceptionThrown when a function receives a value it didn't expect, and it's not valid.

This list covers many common exception classes in PHP, but it's worth noting that PHP has more, and new ones might be introduced in future versions. Furthermore, many PHP libraries and frameworks define their own exception classes to handle domain-specific issues.

Let's expand on the snack vending machine example. Imagine the vending machine accepting a code to vend a particular snack. If a user provides a code that doesn't correspond to any snack in the machine, it will make sense to throw an InvalidArgumentException because the provided argument (in this case, the snack code) is not valid.

function vendSnack($snackCode) {
  $availableSnacks = [
    'A1' => 'Chips',
    'A2' => 'Soda',
    'A3' => 'Candy'
  ];
 
  if (!isset($availableSnacks[$snackCode])) {
    throw new InvalidArgumentException("The provided snack code: $snackCode, is not valid.");
  }
 
  return $availableSnacks[$snackCode];
}
 
echo vendSnack('B5'); // This will throw an exception since 'B5' isn't a valid code in our example.

In the code above, we have a function vendSnack() that expects a valid snack code. The available snacks and their codes are defined in the $availableSnacks array.

If a user tries to vend a snack using a code that's not in the $availableSnacks array (like 'B5' in our example), the function throws an InvalidArgumentException with a message indicating the issue.

By using InvalidArgumentException, we're providing a clear indication of what went wrong: the argument or input provided to the function was not valid. This specificity can help immensely in debugging and error handling.

Custom exceptions

We're not limited to using custom exceptions. You can create your own exceptions since exceptions are created with a class. Custom exceptions are beneficial for several reasons:

  • With custom exceptions, you can define error types that are specific to your application's domain. This means when an error occurs, you can immediately discern its nature based on the exception type, making debugging easier.
  • Different errors often require different handling strategies. By categorizing errors using custom exceptions, you can handle them in ways tailored to their specific needs.
  • Custom exceptions can convey more context and information about an error. When another developer (or even you in the future) looks at the code, the nature and reason for the exception become immediately clear.

Creating a custom exception involves defining a new class that extends the base Exception class or one of its derived classes.

class SnackNotFoundException extends Exception {
  // Additional properties or methods, if needed
}

While the base Exception class provides methods like getMessage(), getCode(), etc., you might want your custom exception to have additional properties or methods specific to its purpose. In most cases, you should be fine with just extending the base class.

After defining it, we can throw our exception. Use the throw keyword to raise your custom exception when a specific condition is met.

if (!isset($availableSnacks[$snackCode])) {
  throw new SnackNotFoundException("Snack with code $snackCode not found.");
}

If you were to run the code now, you would get the following message:

Fatal error: Uncaught SnackNotFoundException: Snack with code B5 not found. in script.php

Here's the complete code:

class SnackNotFoundException extends Exception {
  // Additional properties or methods, if needed
}
 
function vendSnack($snackCode) {
  $availableSnacks = [
    'A1' => 'Chips',
    'A2' => 'Soda',
    'A3' => 'Candy'
  ];
 
  if (!isset($availableSnacks[$snackCode])) {
    throw new SnackNotFoundException("Snack with code $snackCode not found.");
  }
 
  return $availableSnacks[$snackCode];
}
 
echo vendSnack('B5'); // This will throw an exception since 'B5' isn't a valid code in our example.

By following these steps, you can define and use custom exceptions in your PHP applications, leading to more readable, maintainable, and robust error handling.

Key Takeaways

  • Exceptions are a mechanism to handle runtime errors in PHP, allowing the program to catch and deal with them instead of terminating abruptly.
  • Use the throw keyword to raise an exception when a specific condition or error is met.
  • PHP has a foundational exception class named Exception. Most built-in and custom exception types are derived from this class.
  • PHP provides several specialized exception classes, such as InvalidArgumentException, RuntimeException, and more. These help categorize and handle specific error types more precisely.
  • You can create custom exception classes by extending the base Exception class or any of its derivatives.

Comments

Please read this before commenting