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 教程。