PHP版本5发布时,它合并了一个内置模型来捕获错误和异常。使用try catch块处理PHP中的错误与处理其他编程语言中的错误几乎相同。
引发PHP异常时,PHP运行时将查找可以处理该类型异常的catch语句。它将继续检查堆栈跟踪中的调用方法,直到找到catch语句。如果未找到,则将异常传递给全局异常处理程序,我们还将在本文中介绍。
简单的PHP try catch示例
这是一个基本的PHP try catch语句的示例。
try {
// run your code here
}
catch (exception $e) {
//code to handle the exception
}
finally {
//optional code that always runs
}
PHP错误处理关键字
以下关键字用于PHP异常处理。
- 尝试: try块包含可能引发异常的代码。将执行try块中的所有代码,直到可能引发异常为止。
- 抛出: throw关键字用于表示PHP异常的发生。然后,PHP运行时将尝试查找catch语句来处理异常。
- 捕获:仅当try代码块中发生异常时,才会调用此代码块。catch语句中的代码必须处理引发的异常。
- 最终:在PHP 5.5中,引入了finally语句。也可以在catch块之后或代替catch块来指定finally块。无论是否已引发异常,并且在恢复正常执行之前,finally块中的代码将始终在try和catch块之后执行。这对于诸如无论是否发生异常都关闭数据库连接之类的方案很有用。
PHP尝试捕获多种异常类型
PHP支持在try catch中使用多个catch块。这使我们可以根据引发的异常类型来自定义代码。这对于自定义向用户显示错误消息的方式或自定义重试首次失败的内容很有用。
try {
// run your code here
}
catch (Exception $e) {
echo $e->getMessage();
}
catch (InvalidArgumentException $e) {
echo $e->getMessage();
}
何时使用最后尝试
在PHP 5.5版中,添加了finally块。有时在您的PHP错误处理代码中,您还将需要使用finally部分。最后,它不仅用于异常处理,还用于执行清除代码,例如关闭文件,关闭数据库连接等。
当try catch块退出时,finally块总是执行。这样可以确保即使发生意外异常,也可以执行finally块。
最后尝试的示例:
try {
print "this is our try block n";
throw new Exception();
} catch (Exception $e) {
print "something went wrong, caught yah! n";
} finally {
print "this part is always executed n";
}
下图显示了程序的工作方式。
创建自定义PHP异常类型
PHP还允许创建自定义异常类型。这对于在应用程序中创建自定义异常非常有用,您可以在其中进行特殊的异常处理。
要创建自定义异常处理程序,我们必须创建一个特殊类,该类具有在发生异常时可以调用的函数。该类必须是异常类的扩展。
class DivideByZeroException extends Exception {};
自定义异常类继承自PHP的Exception类的属性,您可以向其添加自定义函数。您可能不希望向用户显示异常的所有详细信息,或者可以显示用户友好的消息并在内部记录错误消息以进行监视。
下面的示例使用带有多个catch语句的自定义PHP异常。
class DivideByZeroException extends Exception {};
class DivideByNegativeException extends Exception {};
function process_divide($denominator)
{
try
{
if ($denominator == 0)
{
throw new DivideByZeroException();
}
else if ($denominator < 0)
{
throw new DivideByNegativeException();
}
else
{
echo 100 / $denominator;
}
}
catch (DivideByZeroException $ex)
{
echo "Divide by zero exception!";
}
catch (DivideByNegativeException $ex)
{
echo "Divide by negative number exception!";
}
catch (Exception $x)
{
echo "UNKNOWN EXCEPTION!";
}
}
上面的代码引发异常,并使用自定义异常类捕获它。将DivideByZeroException()和DivideByNegativeException()类创建为现有Exception类的扩展。这样,它继承了Exception类的所有方法和属性。如果分母为零或负数,则执行“ try”块并引发异常。“ catch”块捕获异常并显示错误消息。
下面的流程图总结了上面的示例代码如何用于自定义类型的异常。
全局PHP异常处理
在理想的情况下,您的代码将执行适当的异常处理。作为最佳实践,您还应该配置全局PHP异常处理程序。如果发生未处理的异常,而该异常未在适当的PHP try catch块中调用,则将调用该方法。
要配置全局PHP异常处理程序,我们将使用set_exception_handler()函数设置一个用户定义的函数来处理所有未捕获的异常:
function our_global_exception_handler($exception) {
//this code should log the exception to disk and an error tracking system
echo "Exception:" . $exception->getMessage();
}
set_exception_handler(‘our_global_exception_handler’);
如何在您的PHP try catch块中正确记录异常
在解决应用程序问题时,日志记录通常是大多数开发人员的耳目。记录异常,以便您可以在异常发生后找到它们,这是PHP错误处理最佳实践的重要组成部分。
错误日志在开发过程中至关重要,因为错误日志允许开发人员查看在应用程序运行时记录的警告,错误,通知等。您可以通过我们刚刚学习的PHP异常处理技术try catch适当地处理它们。
根据您使用的PHP框架( Laravel,Codeigniter,Symfony或其他),它们可能提供内置的日志记录框架。您还可以使用Monolog,这是一个标准的PHP日志记录库。无论使用哪种日志记录框架,您都希望始终记录代码中引发的重要异常。
这是记录Monolog错误的try / catch示例:
require_once(DIR.'/vendor/autoload.php');
use MonologLogger;
use MonologHandlerStreamHandler;
$logger = new Logger('channel-name');
$logger->pushHandler(new StreamHandler(DIR.'/app.log', Logger::DEBUG));
try {
// Code does some stuff
// debug logging statement
$logger->info('This is a log! ^_^ ');
}
catch (Exception $ex) {
$logger->error('Oh no an exception happened! ');
}
如何在MySQL中使用try catch
MySQL,PDO和mysqli的PHP库具有不同的错误处理模式。如果没有为这些库启用异常的功能,则不能使用try catch块。这使得错误处理有所不同,并且可能更加复杂。
PDO
在PDO中,创建连接时必须启用ERRMODE_EXCEPTION。
// connect to MySQL
$conn = new PDO('mysql:host=localhost;dbname=stackifydb;charset=utf8mb4', 'username', 'password');
//PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
从PHP文档中了解有关PDO属性的更多信息。
的MySQL
对于mysqli,您必须执行类似的操作:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);