跳转到主要内容

try...catch

try

A ENTITY block delimits a segment of code which might ENTITY a Throwable error that needs handling. A ENTITY block must have at least one corresponding ENTITY or ENTITY block.

When a Throwable error is thrown in a ENTITY block, PHP will attempt to find the first matching ENTITY block to handle the error. If none can be found, the call stack is unwound until a matching ENTITY block is found or the global scope is reached. An uncaught object is then passed to the exception handler set with set_exception_handler, if one is set; otherwise, the script terminates with a fatal error.

catch

A ENTITY block defines how to respond to a thrown Throwable error. It specifies one or more subclasses of Throwable (most commonly Exception) it can handle, and optionally a variable to which the exception is assigned.

The first ENTITY block that matches the class of the thrown Throwable object will handle the error. Normal execution resumes after the ENTITY block without entering any other matching ENTITY blocks.

[!NOTE] It is not recommended to catch Error objects, as they signal a programming error.

Catching an Exception

<?php
try {
    throw new Exception('Error');
} catch (Exception $e) {
    echo 'Caught exception: ', $e->getMessage(), "\n";
}

// Continue execution
echo "Hello World\n";

   

ENTITY

Caught exception: Error
Hello World

As of PHP 7.1.0, a ENTITY block may specify a union of Throwable subclasses that the block should handle using the pipe (|) character. This is useful when different exceptions from different class hierarchies are handled in the same way.

Catching a union of classes to handle

<?php

class MyException extends Exception { }

class MyOtherException extends Exception { }

class Test {
    public function testing() {
        try {
            throw new MyException();
        } catch (MyException | MyOtherException $e) {
            var_dump(get_class($e));
        }
    }
}

$foo = new Test;
$foo->testing();

   

ENTITY

string(11) "MyException"

Multiple ENTITY blocks can be used to handle different classes of Throwable errors in different ways.

Multiple catch blocks

<?php
try {
    do_something_io_related();
} catch (FileNotFoundException $e) {
    // Only catch FileNotFoundException and do something in this case
} catch (MissingPermissionException $e) {
    // Only catch MissingPermissionException and do something different in this case
}

   

Throwables can be ENTITYn (or re-thrown) within a ENTITY block.

Nested Exception

<?php

class MyException extends Exception { }

class Test {
    public function testing() {
        try {
            try {
                throw new MyException('foo!');
            } catch (MyException $e) {
                // rethrow it
                throw $e;
            }
        } catch (Exception $e) {
            var_dump($e->getMessage());
        }
    }
}

$foo = new Test;
$foo->testing();

   

ENTITY

string(4) "foo!"

[!CAUTION] An object thrown inside a ENTITY block will not be caught by an adjacent ENTITY block.

Sequential catch blocks

<?php

class A extends Exception {}
class B extends Exception {}

try {
    throw new A;
} catch (A $e) {
    throw new B;
} catch (B) {
    echo 'Hello';
}


    

ENTITY

Fatal error: Uncaught B in /in/K8Tl9:9
Stack trace:
#0 {main}
  thrown in /in/K8Tl9 on line 9

As of PHP 8.0.0, the variable name for a caught Throwable is optional. If not specified, the ENTITY block will still execute but will not have access to the thrown object.

Omitting the caught variable

Only permitted as of PHP 8.0.0.

<?php

class SpecificException extends Exception {}

function test() {
    throw new SpecificException('Oopsie');
}

try {
    test();
} catch (SpecificException) {
    print "A SpecificException was thrown, but we don't care about the details.";
}

   

ENTITY

A SpecificException was thrown, but we don't care about the details.

See the error handling section for the Throwable hierarchy and how to define custom exceptions.