我可以像这样使用try-catch-finally吗?

时间:2013-02-22 19:10:43

标签: php try-catch-finally

我使用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版本或其他语言中)来处理“如果不存在则创建一些东西”操作吗?

4 个答案:

答案 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版本,但工作方式相同。