簡體   English   中英

我可以像這樣使用try-catch-finally嗎?

[英]Can I use try-catch-finally like this?

我正在使用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版本或其他語言中)用於處理“創建一些不存在的東西”操作嗎?

最后將始終執行,因此在這種情況下,它不是其預期目的,因為正常執行將第二次重新打開文件。 如果你這樣做,你打算用同樣的(更干凈的)方式實現

$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或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還沒有引入PHP,直到5.5版還沒有發布,所以你還沒有看到任何有關它的例子。 因此,除非你正在運行PHP 5.5的alpha版本,否則你finally還是無法使用。

從手冊( 例外

在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';
?>

最后意味着你最想做什么。

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'上使用相同的代碼。 這只是回答你的問題嗎?

我只想指定如果在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塊捕獲了某些內容, catch重新拋出異常。 它不是finally版本,但工作原理相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM