Подтвердить что ты не робот

Могу ли я использовать 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 или других языках) для обработки операций "создать что-то, если они не существуют"?

4b9b3361

Ответ 1

Наконец, всегда будет выполняться, поэтому в этом случае это не его целевая цель, так как нормальное выполнение снова откроет файл. То, что вы намереваетесь сделать, будет достигнуто тем же (более чистым) способом, если вы сделаете

$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
  • ваши попытки или блокировки вызовов блоков возвращаются

Наконец, тогда будет полезно в этом сценарии:

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

= > , если вам нужно убедиться, что вы закрываете обработчик файлов в этом случае или какой-то ресурс в целом.

Ответ 2

finally не был введен в PHP до версии 5.5, которая еще не выпущена, поэтому вы еще не видели никаких примеров. Поэтому, если вы не работаете и альфа-версия PHP 5.5, вы еще не можете использовать finally.

Из руководства (exceptions)

В PHP 5.5 и более поздних версиях блок блоков finally также может быть указан после блоков catch. Код в блоке 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';
?>

Ответ 3

Наконец, означает, что вы хотите сделать Наконец.

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". Это просто ответит на ваш вопрос?

Ответ 4

Я просто хочу назначить, что если исключение происходит в блоке 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
}

Как вы можете видеть, таким образом, независимо от того, что произойдет, временный файл будет удален. Если мы будем эмулировать предложение finally в старой версии PHP, мы должны написать что-то вроде этого:

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

Обратите внимание, что исключение было повторно выбрано, если блок catch поймал что-то. Это не ясно, как версия finally, но работает одинаково.