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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15031515/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 08:25:25  来源:igfitidea点击:

Can I use try-catch-finally like this?

phptry-catch-finally

提问by Kamil

I'm using try-catchfor years, but I never learned how and when to use finally, because I never understood the point of finally(I've read bad books)?

我使用try-catch了多年,但我从未学会如何以及何时使用finally,因为我从来不明白finally(我读过坏书)的意义?

I want to ask you about use of finallyin my case.

我想问你finally在我的情况下使用。

My code example should explain everything:

我的代码示例应该解释一切:

$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);
}

Is this correct use of finally?

这是finally的正确用法吗?

More precise question:

更准确的问题:

Shall I use finally(in future PHP versions or other languages) for handling "create something if it not exists" operations?

我应该使用finally(在未来的 PHP 版本或其他语言中)来处理“如果它不存在就创建”操作?

回答by mika

Finally will always be executed, so in this case, it is not its intended purpose, since normal execution would reopen the file a second time. What you intend to do would be achieved in the same (cleaner) way if you do

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);
}

Then the manual says:

然后手册上说:

For the benefit of someone anyone who hasn't come across finally blocks before, the key difference between them and normal code following a try/catch block is that they will be executed even the try/catch block would return control to the calling function.

It might do this if:

  • code if your try block contains an exception type that you don't catch
  • you throw another exception in your catch block
  • your try or catch block calls return

为了以前没有遇到过 finally 块的人的利益,它们与 try/catch 块之后的普通代码之间的主要区别在于,即使 try/catch 块将控制权返回给调用函数,它们也会被执行。

如果出现以下情况,它可能会这样做:

  • 如果您的 try 块包含您未捕获的异常类型,则编写代码
  • 你在 catch 块中抛出另一个异常
  • 你的 try 或 catch 块调用返回

Finally would then be useful in this kind of scenario:

最后在这种情况下会很有用:

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();
    }
}

=> if you need to make sure you close your file handler in this case, or some resource in general.

=> 如果您需要确保在这种情况下关闭文件处理程序,或者一般情况下关闭某些资源。

回答by John Conde

finallywasn't introduced into PHP until version 5.5 which has not been released yet so that why you haven't seen any examples with it yet. So unless you're running and alpha version of PHP 5.5 you can't use finallyyet.

finally直到版本 5.5 才被引入 PHP,该版本尚未发布,所以您还没有看到任何示例。因此,除非您正在运行 PHP 5.5 的 alpha 版本,否则您还不能使用finally

From the manual (exceptions)

从手册(例外

In PHP 5.5 and later, a finally block may also be specified after the catch blocks. Code within the finally block will always be executed after the try and catch blocks, regardless of whether an exception has been thrown, and before normal execution resumes.

在 PHP 5.5 及更高版本中,也可以在 catch 块之后指定 finally 块。finally 块中的代码将始终在 try 和 catch 块之后执行,无论是否抛出异常,并且在恢复正常执行之前。

Example from the manual of using finally

使用手册中的示例 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';
?>

回答by Mayukh Roy

Finally means what do you want to DO 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
}

No matter what happens(regardless of whether an exception has been thrown) inside try or catch, 'Finally code' will execute. So, no point of using same code over 'try' and 'finally'. Does this simply answer your question?

无论在 try 或 catch 中发生什么(无论是否抛出异常),“最终代码”都会执行。因此,在“尝试”和“最终”上使用相同的代码毫无意义。这是否只是回答了您的问题?

回答by Iazel

I just want to appoint that if an Exception occurs in the tryblock, the exception will be correctly raised even if the finallyblock is present. The usefulness of the finallyblock is for clean and free resources. I think it's best use is when, for example, you upload a file but then an error happens:

我只想指定如果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
}

As you can see, in this way no matter what happen, the temp file will be correctly deleted.
If we would emulate the finallyclause in older version of PHP, we should write something like this:

如您所见,这样无论发生什么,临时文件都会被正确删除。
如果我们要模拟finally旧版本 PHP 中的子句,我们应该这样写:

// start finally
catch(Exception $ex) {
}
if($tmp_name)
    unlink($tmp_name);
if( isset($ex) )
    throw $ex;
// end finally

Note that the exception has been re-thrown in case the catchblock caught something. It isn't clear as the finallyversion, but works the same.

请注意,如果catch块捕获到某些内容,则已重新抛出异常。它的finally版本不清楚,但工作原理相同。