PHP try/catch/finally 语句
最后修改于 2025 年 4 月 16 日
PHP 的 try
、catch
和 finally
语句对于异常处理至关重要。它们允许进行优雅的错误恢复和清理操作。这些结构有助于管理 PHP 中的运行时错误。
基本定义
try
块包含可能抛出异常的代码。catch
块处理从 try 块抛出的异常。
finally
块无论是否抛出异常都会执行代码。它是进行清理操作(如关闭文件或连接)的理想选择。
语法:try { code } catch (ExceptionType $e) { handle } finally { cleanup }
。异常是代表执行过程中发生的错误的.*对象。
基本 try-catch
此示例演示了一个处理除零错误的简单 try-catch 块。
<?php declare(strict_types=1); try { $result = 10 / 0; echo "Result: $result"; } catch (DivisionByZeroError $e) { echo "Error: Cannot divide by zero"; }
代码尝试在 try 块中进行除零操作。这会抛出 DivisionByZeroError。catch 块会捕获此特定异常类型。错误消息会显示出来,而不是导致程序崩溃。
多个 catch 块
此示例展示了如何使用多个 catch 来处理不同的异常类型。
<?php declare(strict_types=1); try { $file = fopen("nonexistent.txt", "r"); $content = fread($file, 100); fclose($file); } catch (RuntimeException $e) { echo "Runtime error: " . $e->getMessage(); } catch (Exception $e) { echo "General error: " . $e->getMessage(); }
代码尝试打开一个不存在的文件。这会抛出 RuntimeException。第一个 catch 专门处理运行时错误。第二个 catch 捕获所有其他异常。应该先捕获更具体的异常。
Finally 块
此示例演示了如何使用 finally 进行清理操作。
<?php declare(strict_types=1); $resource = null; try { $resource = fopen("data.txt", "w"); fwrite($resource, "Hello World"); } catch (Exception $e) { echo "Error: " . $e->getMessage(); } finally { if ($resource) { fclose($resource); echo "Resource closed"; } }
代码在 try 块中打开文件并向其写入。finally 块确保文件无论是否发生异常都会被关闭。这可以防止资源泄露。finally 块始终会执行。
自定义异常
此示例展示了如何创建和抛出自定义异常。
<?php declare(strict_types=1); class InvalidEmailException extends Exception {} function validateEmail(string $email): bool { if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { throw new InvalidEmailException("Invalid email format"); } return true; } try { validateEmail("invalid-email"); } catch (InvalidEmailException $e) { echo "Validation error: " . $e->getMessage(); }
代码定义了一个自定义的 InvalidEmailException 类。validateEmail 函数在电子邮件无效时抛出此异常。catch 块会处理此特定异常类型。自定义异常可以使错误处理更清晰。
嵌套 try-catch
此示例演示了如何使用嵌套的 try-catch 块进行复杂的错误处理。
<?php declare(strict_types=1); try { try { $result = 10 / 0; } catch (DivisionByZeroError $e) { throw new Exception("Calculation failed", 0, $e); } } catch (Exception $e) { echo "Outer catch: " . $e->getMessage(); echo "Previous: " . $e->getPrevious()->getMessage(); }
内部 try 尝试进行除零操作。内部 catch 将错误转换为更通用的 Exception。外部 catch 会处理此异常,并通过 getPrevious() 访问原始错误。这允许进行错误包装和传播。
异常信息
此示例展示了如何在 catch 块中访问异常详细信息。
<?php declare(strict_types=1); try { $array = [1, 2, 3]; echo $array[5]; } catch (OutOfBoundsException $e) { echo "Error: " . $e->getMessage() . "\n"; echo "File: " . $e->getFile() . "\n"; echo "Line: " . $e->getLine() . "\n"; echo "Trace: " . $e->getTraceAsString() . "\n"; }
代码尝试访问无效的数组索引。catch 块展示了如何获取详细的错误信息。getMessage() 返回错误描述。getFile() 和 getLine() 显示错误发生的位置。getTraceAsString() 提供调用堆栈。
全局异常处理程序
此示例演示了如何设置全局异常处理程序。
<?php declare(strict_types=1); function globalExceptionHandler(Throwable $e) { echo "Global handler caught: " . $e->getMessage(); error_log("Uncaught exception: " . $e->getMessage()); } set_exception_handler('globalExceptionHandler'); // This exception won't be caught by any try-catch throw new Exception("Something went wrong");
代码设置了一个全局异常处理函数。此函数将捕获脚本中任何未捕获的异常。处理程序会记录错误并显示一条消息。全局处理程序对于集中错误日志记录和显示非常有用。
最佳实践
- 特定捕获:先捕获特定的异常类型。
- 清理:使用 finally 进行资源清理操作。
- 日志记录:记录异常以供调试。
- 自定义异常:创建特定于域的异常。
- 优雅恢复:在可能的情况下提供备用行为。
来源
本教程介绍了 PHP 异常处理,并通过实际示例展示了 try、catch 和 finally 在各种场景下的用法。
作者
列出 所有 PHP 教程。