我使用try-catch
多年了,但我从未学会如何以及何时使用finally
,因为我从未理解finally
的意义(我读过坏书)?
我想问你关于在我的情况下使用finally
的问题。
我的代码示例应该解释一切:
$s = "";
$c = MyClassForFileHandling::getInstance();
try
{
$s = $c->get_file_content($path);
}
catch FileNotFoundExeption
{
$c->create_file($path, "text for new file");
}
finally
{
$s = $c->get_file_content($path);
}
finally的用法正确吗?
更精确的问题:
我应该使用finally
(在未来的PHP版本或其他语言中)来处理"如果不存在就创建一些东西"操作吗?
Finally将始终被执行,因此在这种情况下,它不是其预期目的,因为正常执行会第二次重新打开文件。如果你进行,你打算做的事情将以同样(更清洁)的方式实现
$s = "";
$c = MyClassForFileHandling::getInstance();
try
{
$s = $c->get_file_content($path);
}
catch(FileNotFoundExeption $e)
{
$c->create_file($path, "text for new file");
$s = $c->get_file_content($path);
}
然后手册上写着:
对于以前没有遇到过finally块的人来说,它们与try/catch块后面的普通代码之间的关键区别在于,即使try/catch区块将控制权返回给调用函数,它们也会被执行。
如果
- 如果try块包含未捕获的异常类型,则执行代码
- 在catch块中抛出另一个异常
- 您的try-or-catch阻止调用返回
最后在这种情况下是有用的:
function my_get_file_content($path)
{
try
{
return $c->get_file_content($path);
}
catch(FileNotFoundExeption $e)
{
$c->create_file($path, "text for new file");
return $c->get_file_content($path);
}
finally
{
$c->close_file_handler();
}
}
=>如果您需要确保在这种情况下关闭文件处理程序,或者关闭某些资源。
finally
直到5.5版才被引入PHP,而5.5版还没有发布,所以你还没有看到任何关于它的例子。因此,除非您运行的是PHP 5.5的alpha版本,否则您还不能使用finally
。
来自手册(例外)
在PHP5.5及更高版本中,还可以在catch块之后指定finally块。finally块中的代码将始终在try-and-catch块之后执行,无论是否引发异常,并且在恢复正常执行之前执行。
使用finally
的手册示例
<?php
function inverse($x) {
if (!$x) {
throw new Exception('Division by zero.');
}
else return 1/$x;
}
try {
echo inverse(5) . "n";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "n";
} finally {
echo "First finally.n";
}
try {
echo inverse(0) . "n";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "n";
} finally {
echo "Second finally.n";
}
// Continue execution
echo 'Hello World';
?>
Finally表示您想做什么Finally。
try
{
$s = $c->get_file_content($path);
}
catch FileNotFoundExeption
{
$c->create_file($path, "text for new file");
}
finally
{
//Create a pdf with my file
//or, Rename my file
//or, store my file into Database
}
无论try或catch内部发生什么(无论是否抛出异常),"Finally代码"都将执行。所以,在"try"one_answers"finally"之间使用相同的代码是没有意义的。这简单地回答了你的问题吗?
我只想指定,如果try
块中发生异常,即使存在finally
块,也会正确引发异常。finally
块的有用性是用于干净和免费的资源。我认为它的最佳用途是,例如,当你上传一个文件,但随后发生错误:
$tmp_name = null;
try {
$tmp_name = tempnam(UPLOAD_DIR, 'prefix');
move_uploaded_file($file['tmp_name'], $tmp_name);
ImageManager::resize($tmp_name, $real_path, $width, $height); // this will rise some exception
}
finally {
if($tmp_name)
unlink($tmp_name); // this will ensure the temp file is ALWAYS deleted
}
正如您所看到的,通过这种方式,无论发生什么,临时文件都将被正确删除
如果我们要在旧版本的PHP中模拟finally
子句,我们应该写这样的东西:
// start finally
catch(Exception $ex) {
}
if($tmp_name)
unlink($tmp_name);
if( isset($ex) )
throw $ex;
// end finally
请注意,在catch
块捕获到某些内容的情况下,已重新抛出异常。它与finally
版本不清楚,但工作原理相同。