我最后可以这样用try-catch吗



我使用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版本不清楚,但工作原理相同。

相关内容

  • 没有找到相关文章

最新更新