我使用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
(在将来的PHP版本或其他语言中)来处理“如果不存在则创建一些东西”操作吗?
答案 0 :(得分:31)
最后将始终执行,因此在这种情况下,它不是其预期目的,因为正常执行将第二次重新打开文件。如果你这样做,你打算用同样的(更干净的)方式做什么
$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);
}
然后手册说:
为了某人之前没有遇到过最终阻止的人的利益,他们和try / catch块之后的正常代码之间的关键区别在于它们将被执行,即使try / catch块也会将控制权返回给调用函数。
如果出现以下情况,可能会这样做:
- 代码,如果您的try块包含您未捕获的异常类型
- 你在catch块中抛出另一个异常
- 你的try或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();
}
}
=>如果你需要确保在这种情况下关闭文件处理程序,或者一般的某些资源。
答案 1 :(得分:4)
finally
在版本5.5之前尚未引入到PHP中,尚未发布,所以为什么你还没有看到它的任何例子。因此,除非您正在运行PHP 5.5的alpha版本,否则您无法使用finally
。
来自手册(exceptions)
在PHP 5.5及更高版本中,也可以在catch块之后指定finally块。 finally块中的代码将始终在try和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';
?>
答案 2 :(得分:0)
最后意味着你最想做什么。
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 code”都会执行。 所以,没有必要在'try'和'finally'上使用相同的代码。 这只是回答你的问题吗?
答案 3 :(得分:0)
我只想指定如果在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
版本,但工作方式相同。