The try…catch block

Your code can throw exceptions manually whenever you think it necessary. For example, take the method from the trait. Thanks to type hinting, we are enforcing the ID to be a numeric one, but that is as far as it goes. What would happen if someone tries to set an ID that is a negative number? The code right now allows it to go through, but depending on your preferences, you would like to avoid it. That would be a good place for an exception to happen. Let's see how we would add this check and consequent exception:

public function setId($id) {
    if ($id < 0) {
        throw new \Exception('Id cannot be negative.');
    }
    if (empty($id)) {
        $this->id = ++self::$lastId;
    } else {
        $this->id = $id;
        if ($id > self::$lastId) {
            self::$lastId = $id;
        }
    }
}

As you can see, exceptions are objects of the class exception. Remember adding the backslash to the name of the class, unless you want to include it with at the top of the file. The constructor of the class takes some optional arguments, the first one of them being the message of the exception. Instances of the class do nothing by themselves; they have to be thrown in order to be noticed by the program.

Let's try forcing our program to throw this exception. In order to do that, let's try to create a customer with a negative ID. In your file, add the following:

$basic = new Basic(-1, "name", "surname", "email");

If you try it now in your browser, PHP will throw a fatal error saying that there was an uncaught exception, which is the expected behavior. For PHP, an exception is something from what it cannot recover, so it will stop execution. That is far from ideal, as you would like to just display an error message to the user, and let them try again.

You can—and should—capture exceptions using the blocks. You insert the code that might throw an exception in the block and if an exception happens, PHP will jump to the block. Let's see how it works:

public function setId(int $id) {
    try {
        if ($id < 0) {
            throw new Exception('Id cannot be negative.');
        }
        if (empty($id)) {
            $this->id = ++self::$lastId;
        } else {
            $this->id = $id;
            if ($id > self::$lastId) {
                self::$lastId = $id;
            }
        }
    } catch (Exception $e) {
        echo $e->getMessage();
    }
}

If we test the last code snippet in our browser, we will see the message printed from the block. Calling the method on an exception instance will give us the message—the first argument when creating the object. But remember that the argument of the constructor is optional; so, do not rely on the message of the exception too much if you are not sure how it is generated, as it might be empty.

Note that after the exception is thrown, nothing else inside the block is executed; PHP goes straight to the block. Additionally, the block gets an argument, which is the exception thrown. Here, type hinting is mandatory—you will see why very soon. Naming the argument as is a widely used convention, even though it is not a good practice to use poor descriptive names for variables.

Being a bit critical, so far, there is not any real advantage to be seen in using exceptions in this example. A simple block would do exactly the same job, right? But the real power of exceptions lies in the ability to be propagated across methods. That is, the exception thrown on the method, if not captured, will be propagated to wherever the method was invoked, allowing us to capture it there. This is very useful, as different places in the code might want to handle the exception in a different way. To see how this is done, let's remove the inserted in , and place the following piece of code in your file, instead:

try {
    $basic = new Basic(-1, "name", "surname", "email");
} catch (Exception $e) {
    echo 'Something happened when creating the basic customer: '
        . $e->getMessage();
}

The preceding example shows how useful it is to catch propagated exceptions: we can be more specific of what happens, as we know what the user was trying to do when the exception was thrown. In this case, we know that we were trying to create the customer, but this exception might have been thrown when trying to update the ID of an existing customer, which would need a different error message.

Learning PHP 7
titlepage.xhtml
part0000.html
part0001.html
part0002.html
part0003.html
part0004.html
part0005.html
part0006.html
part0007_split_000.html
part0007_split_001.html
part0007_split_002.html
part0008_split_000.html
part0008_split_001.html
part0009.html
part0010.html
part0011.html
part0012.html
part0013_split_000.html
part0013_split_001.html
part0013_split_002.html
part0013_split_003.html
part0013_split_004.html
part0014_split_000.html
part0014_split_001.html
part0014_split_002.html
part0014_split_003.html
part0014_split_004.html
part0015_split_000.html
part0015_split_001.html
part0015_split_002.html
part0015_split_003.html
part0015_split_004.html
part0016_split_000.html
part0016_split_001.html
part0016_split_002.html
part0016_split_003.html
part0016_split_004.html
part0017_split_000.html
part0017_split_001.html
part0017_split_002.html
part0017_split_003.html
part0018.html
part0019_split_000.html
part0019_split_001.html
part0019_split_002.html
part0019_split_003.html
part0019_split_004.html
part0020_split_000.html
part0020_split_001.html
part0021_split_000.html
part0021_split_001.html
part0021_split_002.html
part0021_split_003.html
part0022.html
part0023_split_000.html
part0023_split_001.html
part0024_split_000.html
part0024_split_001.html
part0025_split_000.html
part0025_split_001.html
part0025_split_002.html
part0025_split_003.html
part0025_split_004.html
part0025_split_005.html
part0025_split_006.html
part0026.html
part0027_split_000.html
part0027_split_001.html
part0027_split_002.html
part0027_split_003.html
part0027_split_004.html
part0027_split_005.html
part0027_split_006.html
part0027_split_007.html
part0028_split_000.html
part0028_split_001.html
part0028_split_002.html
part0028_split_003.html
part0028_split_004.html
part0029_split_000.html
part0029_split_001.html
part0029_split_002.html
part0029_split_003.html
part0030_split_000.html
part0030_split_001.html
part0030_split_002.html
part0030_split_003.html
part0030_split_004.html
part0031_split_000.html
part0031_split_001.html
part0031_split_002.html
part0031_split_003.html
part0032.html
part0033_split_000.html
part0033_split_001.html
part0033_split_002.html
part0033_split_003.html
part0033_split_004.html
part0033_split_005.html
part0034_split_000.html
part0034_split_001.html
part0035.html
part0036.html
part0037_split_000.html
part0037_split_001.html
part0037_split_002.html
part0038_split_000.html
part0038_split_001.html
part0038_split_002.html
part0038_split_003.html
part0039_split_000.html
part0039_split_001.html
part0040.html
part0041_split_000.html
part0041_split_001.html
part0041_split_002.html
part0041_split_003.html
part0042_split_000.html
part0042_split_001.html
part0042_split_002.html
part0043.html
part0044.html
part0045_split_000.html
part0045_split_001.html
part0045_split_002.html
part0046_split_000.html
part0046_split_001.html
part0046_split_002.html
part0046_split_003.html
part0047_split_000.html
part0047_split_001.html
part0047_split_002.html
part0047_split_003.html
part0047_split_004.html
part0048.html
part0049.html
part0050_split_000.html
part0050_split_001.html
part0050_split_002.html
part0050_split_003.html
part0051.html
part0052.html
part0053_split_000.html
part0053_split_001.html
part0053_split_002.html
part0053_split_003.html
part0054.html
part0055.html
part0056_split_000.html
part0056_split_001.html
part0057_split_000.html
part0057_split_001.html
part0057_split_002.html
part0057_split_003.html
part0057_split_004.html
part0058_split_000.html
part0058_split_001.html
part0058_split_002.html
part0058_split_003.html
part0058_split_004.html
part0059_split_000.html
part0059_split_001.html
part0059_split_002.html
part0059_split_003.html
part0060_split_000.html
part0060_split_001.html
part0060_split_002.html
part0060_split_003.html
part0060_split_004.html
part0060_split_005.html
part0060_split_006.html
part0060_split_007.html
part0061_split_000.html
part0061_split_001.html
part0061_split_002.html
part0061_split_003.html
part0061_split_004.html
part0061_split_005.html
part0062_split_000.html
part0062_split_001.html
part0062_split_002.html
part0063.html
part0064_split_000.html
part0064_split_001.html
part0064_split_002.html
part0064_split_003.html
part0065_split_000.html
part0065_split_001.html
part0065_split_002.html
part0065_split_003.html
part0066_split_000.html
part0066_split_001.html
part0066_split_002.html
part0066_split_003.html
part0066_split_004.html
part0067_split_000.html
part0067_split_001.html
part0067_split_002.html
part0067_split_003.html
part0068.html
part0069_split_000.html
part0069_split_001.html
part0070.html
part0071_split_000.html
part0071_split_001.html
part0071_split_002.html
part0071_split_003.html
part0072_split_000.html
part0072_split_001.html
part0072_split_002.html
part0072_split_003.html
part0072_split_004.html
part0073_split_000.html
part0073_split_001.html
part0073_split_002.html
part0074_split_000.html
part0074_split_001.html
part0074_split_002.html
part0074_split_003.html
part0075_split_000.html
part0075_split_001.html
part0075_split_002.html
part0075_split_003.html
part0075_split_004.html
part0075_split_005.html
part0075_split_006.html
part0075_split_007.html
part0076_split_000.html
part0076_split_001.html
part0076_split_002.html
part0076_split_003.html
part0076_split_004.html
part0077.html
part0078.html
part0079_split_000.html
part0079_split_001.html
part0080.html
part0081_split_000.html
part0081_split_001.html
part0081_split_002.html
part0081_split_003.html
part0082_split_000.html
part0082_split_001.html
part0082_split_002.html
part0082_split_003.html
part0082_split_004.html
part0083_split_000.html
part0083_split_001.html
part0083_split_002.html
part0084_split_000.html
part0084_split_001.html
part0084_split_002.html
part0084_split_003.html
part0084_split_004.html
part0084_split_005.html
part0085_split_000.html
part0085_split_001.html
part0085_split_002.html
part0085_split_003.html
part0085_split_004.html
part0085_split_005.html
part0086.html
part0087.html
part0088_split_000.html
part0088_split_001.html
part0088_split_002.html
part0088_split_003.html
part0088_split_004.html
part0088_split_005.html
part0089_split_000.html
part0089_split_001.html
part0089_split_002.html
part0089_split_003.html
part0089_split_004.html
part0090_split_000.html
part0090_split_001.html
part0090_split_002.html
part0090_split_003.html
part0091.html
part0092_split_000.html
part0092_split_001.html
part0092_split_002.html
part0092_split_003.html
part0092_split_004.html
part0092_split_005.html
part0092_split_006.html
part0092_split_007.html
part0092_split_008.html
part0092_split_009.html
part0092_split_010.html
part0092_split_011.html
part0092_split_012.html
part0092_split_013.html
part0092_split_014.html
part0092_split_015.html
part0092_split_016.html
part0092_split_017.html
part0092_split_018.html
part0092_split_019.html
part0092_split_020.html
part0092_split_021.html
part0092_split_022.html
part0092_split_023.html
part0092_split_024.html