keywod'finally'如何在PHP中使用
所以,我一直在阅读关于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'消息,即使那些我不知道这个用法。 但我不undersand这一点,即使我们赶上LogicException
与捕捉(LogicException $e)
及无异常被抛出还是我们将看到的功能是执行,我们将看到“喜”的消息。 如在这个例子中
try {
throw new LogicException("Throw logic n");
} catch (LogicException $e) {
echo $e->getMessage();
}finally{
echo hi();
}
输出
// Throw logic
// Hi
所以,即使我们没有捕获异常,我们仍然可以看到函数hi()
被执行。 为什么和这有什么用? 我认为finally块被用作万一未发现异常的最后手段,即使情况并非如此,那么为什么它可以用来运行它?
finally
每次都执行
无论是例外还是回报
例外
我看到的一个更常见的用途是关闭数据库连接 - 您希望每次都发生这种情况(有或没有例外),因此您最终不会遇到阻止数据库服务器接受新连接的悬挂连接。
考虑这个伪代码:
try {
$database->execute($sql);
} catch (Exception $exception) {
$logger->log($exception->getMessage());
throw $exception;
} finally {
$database->close();
}
所以在这里我们将总是关闭数据库连接。 如果这是一个正常的查询,我们会在成功后关闭连接。 如果这是一个错误的查询,那么在抛出异常之后我们仍然关闭。
请注意,这种行为在其他语言中是不同的。 例如,在.NET中,如果从catch块中抛出/重新抛出异常,那么finally块将不会执行。
返回
其中一个比较晦涩的行为是它在return语句后执行代码的能力。
这里你可以在函数返回后设置一个变量:
function foo(&$x)
{
try {
$x = 'trying';
return $x;
} finally {
$x = 'finally';
}
}
$bar = 'main';
echo foo($bar) . $bar;
tryingfinally
但是分配将是尝试返回的内容:
$bar = foo($bar);
echo $bar . $bar;
tryingtrying
并在终于返回覆盖尝试返回:
function baz()
{
try {
return 'trying';
} finally {
return 'finally';
}
}
echo baz();
最后
注意这个行为在php 5中有所不同:
finallyfinally
finallyfinally
最后
https://3v4l.org/biO4e
try {
throw new LogicException("Throw logic n"); -> LogicException thrown
} catch (InvalidArgumentException $e) { -> LogicException not catched
echo $e->getMessage();
}finally{
echo hi(); -> code executed. "Hi" printed out
}
LogicException is here -> Fatal error
所以在这种情况下:
try {
throw new LogicException("Throw logic n"); -> LogicException thrown
} catch (InvalidArgumentException $e) { -> LogicException not catched
echo $e->getMessage();
}finally{
echo hi(); -> code executed
die();
}
由于陈述和最后的变化,将不会引发致命错误:
try {
throw new LogicException("Throw logic n"); -> LogicException thrown
} catch (InvalidArgumentException $e) { -> LogicException not catched
echo $e->getMessage();
} catch (LogicException $e) { -> LogicException catched
echo $e->getMessage();
}finally{
echo hi(); -> code executed
}
最后应该包含任何需要执行的代码,而不管是否有例外。
没有最后:
try {
$handle = fopen("file.txt");
//Do stuff
fclose($handle);
return something;
} catch (Exception $e) {
// Log
if (isset($handle) && $handle !== false) {
fclose($handle);
}
}
终于:
try {
$handle = fopen("file.txt");
return something;
} catch (Exception $e) {
// Log
} finally {
if (isset($handle) && $handle !== false) {
fclose($handle);
}
}
在函数返回后需要释放资源的情况下,会出现一些问题。
这在以下情况下变得更有用:
try {
$handle = fopen("file.txt");
if (case1) { return result1; }
if (case2) { return result2; }
if (case3) { return result3; }
if (case4) { return result4; }
} finally {
if (isset($handle) && $handle !== false) {
fclose($handle);
}
}
在这种情况下,可以减少所需的所有fclose
每次回到单一之前调用fclose
将在方法返回之前正确的,但之后的任何其他代码执行调用。
上一篇: How keywod 'finally' is meant to be used in PHP
下一篇: Visual Studio 2015 (C++) : Stop compile on first build error (not first project)