PHP throw 语句
最后修改于 2025 年 4 月 16 日
PHP throw
关键字用于在代码中手动触发异常。 异常是一种强大的错误处理机制,允许您优雅地处理错误。 throw 语句与 try-catch 块一起使用,以实现可靠的错误处理。
基本定义
throw
语句在 PHP 中引发异常。 当抛出时,执行停止,PHP 查找匹配的 catch 块。 异常必须是实现 Throwable 接口的对象。
内置的 Exception 是 PHP 中所有异常的基类。 您还可以通过扩展 Exception 来创建自定义异常类。 异常会通过调用堆栈冒泡,直到被捕获。
语法:throw new Exception("错误消息");
。 throw 关键字后跟一个异常对象。 异常消息应清楚地描述错误。
基本 throw 示例
此示例演示了 throw 关键字的最简单用法。
<?php function divide($numerator, $denominator) { if ($denominator == 0) { throw new Exception("Division by zero"); } return $numerator / $denominator; } try { echo divide(10, 0); } catch (Exception $e) { echo "Caught exception: " . $e->getMessage(); }
当尝试除以零时,代码会抛出异常。 try 块包含可能抛出异常的代码。 catch 块处理异常并显示其消息。 这可以防止致命错误。
自定义异常类
此示例演示如何创建和使用自定义异常类。
<?php class InvalidEmailException extends Exception {} function validateEmail($email) { if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { throw new InvalidEmailException("Invalid email format"); } return true; } try { validateEmail("invalid-email"); } catch (InvalidEmailException $e) { echo "Email error: " . $e->getMessage(); }
该代码定义了一个自定义的 InvalidEmailException 类。 validateEmail 函数为无效电子邮件抛出此异常。 自定义异常使错误处理更加具体。 它们可以包含其他方法。
多个 catch 块
此示例演示如何分别处理不同的异常类型。
<?php class FileNotFoundException extends Exception {} class PermissionDeniedException extends Exception {} function openFile($filename) { if (!file_exists($filename)) { throw new FileNotFoundException("File not found"); } if (!is_readable($filename)) { throw new PermissionDeniedException("Permission denied"); } return fopen($filename, 'r'); } try { openFile("nonexistent.txt"); } catch (FileNotFoundException $e) { echo "File error: " . $e->getMessage(); } catch (PermissionDeniedException $e) { echo "Permission error: " . $e->getMessage(); } catch (Exception $e) { echo "General error: " . $e->getMessage(); }
代码有多个 catch 块用于不同的异常类型。 应该首先捕获更具体的异常。 最后一个 catch 块处理任何剩余的 Exception 类型。 这允许定制的错误处理。
重新抛出异常
此示例展示了如何捕获异常并重新抛出它。
<?php function processData($data) { if (empty($data)) { throw new InvalidArgumentException("Empty data"); } // Process data here } function handleRequest($data) { try { processData($data); } catch (InvalidArgumentException $e) { error_log("Invalid data: " . $e->getMessage()); throw $e; // Rethrow the exception } } try { handleRequest([]); } catch (Exception $e) { echo "Request failed: " . $e->getMessage(); }
该代码捕获一个异常,记录它,然后重新抛出它。 这允许部分处理,同时让更高级别知道错误。 再次抛出相同的异常对象。 重新抛出对于日志记录很有用。
带有附加数据的异常
此示例演示了扩展 Exception 以包含额外数据。
<?php class ValidationException extends Exception { private $errors; public function __construct($message, $errors) { parent::__construct($message); $this->errors = $errors; } public function getErrors() { return $this->errors; } } function validateUser($user) { $errors = []; if (empty($user['name'])) { $errors[] = "Name is required"; } if (empty($user['email'])) { $errors[] = "Email is required"; } if (!empty($errors)) { throw new ValidationException("Validation failed", $errors); } } try { validateUser(['age' => 25]); } catch (ValidationException $e) { echo $e->getMessage() . ": "; print_r($e->getErrors()); }
自定义 ValidationException 存储验证错误。 构造函数接受消息和错误详细信息。 getErrors 方法提供对附加数据的访问。 这种模式对于表单验证很有用。
Finally 块
此示例显示了始终执行的 finally 块。
<?php function processFile($filename) { $file = null; try { $file = fopen($filename, 'r'); if (!$file) { throw new Exception("Failed to open file"); } // Process file contents } catch (Exception $e) { echo "Error: " . $e->getMessage(); } finally { if ($file) { fclose($file); echo "File handle closed"; } } } processFile("example.txt");
无论是否发生异常,finally 块都会执行。 它非常适合清理代码,例如关闭文件。 无论成功与否,文件句柄都会被关闭。 finally 确保资源得到正确释放。
错误 vs 异常
此示例演示了为不可恢复的问题抛出 Error。
<?php function checkMemoryLimit() { $memoryLimit = ini_get('memory_limit'); $usedMemory = memory_get_usage(true); if ($usedMemory > 0.9 * $this->convertToBytes($memoryLimit)) { throw new Error("Memory limit exceeded"); } } function convertToBytes($size) { // Conversion logic here return 0; } try { checkMemoryLimit(); } catch (Error $e) { echo "Fatal error: " . $e->getMessage(); // Log and exit gracefully }
该代码为关键问题(如内存耗尽)抛出 Error。 错误通常表明不可恢复的问题。 它们可以像异常一样被捕获。 PHP 7+ 在 Throwable 下统一了异常和错误。 谨慎使用 Error。
最佳实践
- 特定异常: 为不同的错误类型创建自定义异常。
- 有意义的消息: 提供清晰、可操作的错误消息。
- 正确的日志记录: 在处理或重新抛出之前记录异常。
- 捕获顺序: 在一般异常之前捕获更具体的异常。
- 资源清理: 使用 finally 块释放资源。
来源
本教程介绍了 PHP 异常处理,并提供了实际示例,展示了在各种场景中使用 throw 的方法,以及 try-catch 块。
作者
列出 所有 PHP 教程。