所以,我今天一直在阅读PHP在线手册上的异常,并意识到我还没有理解finally关键字的用途或真正的必要性。我读了这里的一些帖子,所以我的问题略有不同。
我理解我们可以用最后这样的方式:
function hi(){
return 'Hi';
}
try {
throw new LogicException("Throw logic \n");
} catch (InvalidArgumentException $e) {
echo $e->getMessage();
}
echo hi();
输出:
Fatal error: Uncaught LogicException: Throw Logic in C:\Users\...a.php:167
Stack trace:
#0 {main}
thrown in C:\Users\...a.php on line 167
在这种情况下,函数hi();是没有被执行,并有一个很好的理由。我明白,如果异常是不处理php解释器停止脚本。好。到目前为止,从我读到的,终于使我们能够执行函数hi();即使未处理异常(即使我不知道原因)
所以,这个我理解。
try {
throw new LogicException("Throw logic \n");
} catch (InvalidArgumentException $e) {
echo $e->getMessage();
}finally{
echo hi();
}
输出:
Hi
Fatal error: Uncaught LogicException: Throw Logic in C:\Users\...a.php:167
Stack trace:
#0 {main}
thrown in C:\Users\...a.php on line 167
这应该是异常错误,以及来自函数的'hi'消息,即使我不知道它的任何用法,但我不明白的是,即使我们用catch (LogicException $e)
捕获LogicException
并且没有抛出异常,我们仍然会看到函数正在执行,我们会看到'hi'消息,就像这个例子
try {
throw new LogicException("Throw logic \n");
} catch (LogicException $e) {
echo $e->getMessage();
}finally{
echo hi();
}
产出
// Throw logic
// Hi
所以,我们仍然可以看到函数hi()
被执行,即使我们没有未捕获的异常,为什么这样做呢?我认为finally块是作为最后的手段,以防异常没有被捕获,即使不是这样,为什么要运行它呢?
4条答案
按热度按时间1cosmwyk1#
finally
每 * †次执行一次无论错误、异常甚至
return
语句如何,finally
代码块都将运行。try
或catch
块执行die
/exit
,则它 * 不会 * 运行。异常
一个示例是在进程中关闭数据库连接,否则可能会留下悬空连接,从而阻止数据库服务器接受新连接。
考虑下面的伪代码:
这里我们总是关闭数据库连接,如果是正常查询,成功后关闭连接,脚本继续执行。
如果这是一个错误的查询,那么我们仍然在抛出异常后关闭,并且未捕获的异常将冒泡。
下面是
catch
执行一些日志记录的示例。这将使它关闭连接,无论有无异常。
返回
比较模糊的行为之一是它在return语句之后执行代码的能力。
在这里,您可以在函数返回后设置变量:
终于
但try中返回的是赋值语句
尝试
并且finally中的返回将覆盖try中的返回:
终于
最后
最后
终于
https://3v4l.org/biO4e
异常退货
你可以让它看起来像是同时抛出两个异常:
https://3v4l.org/2AYmF
但是,您无法真正捕获我所知道的"第一个"异常来在运行时执行任何有趣的操作:
终于被抓住了
https://3v4l.org/Jknpm
* 死亡
如果执行
exit
ordie
,则finally
块将不会执行。尝试
https://3v4l.org/pc9oc
†硬件故障
最后,您应该理解,如果有人拔掉服务器上的电源插头,
finally
块将不会执行,尽管我没有测试它,但我希望内存耗尽也会跳过它。😉 and although I haven't tested it, I'd expect memory exhaustion to skip it too.8fq7wneg2#
Finally应该包含任何需要执行的代码,无论是否存在异常。
没有最后:
最后:
在函数返回后需要释放资源的情况下,提供了一些整理功能。
这在类似以下的情况下变得更加有用:
在这种情况下,您可以将每次返回之前所需的所有
fclose
调用减少为一个fclose
调用,该调用将在方法返回之前但在任何其他代码之后执行。n9vozmp43#
因此在本例中:
由于die语句和最后一个变量,将不会引发致命错误:
odopli944#
我做了一个小的单元测试来展示它是如何工作的