2013-02-22 4 views
13

Я использую try-catch годами, но я никогда не узнавал, как и когда использовать finally, потому что я никогда не понимал смысла finally (я читал плохие книги)?Могу ли я использовать try-catch-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); 
} 

Вопрос:

Является ли это правильное использование, наконец?

Edit: Более точный вопрос:

Должен ли я использовать finally (в будущем PHP версии или другие языки) для обработки «создать что-то, если он не существует» операции?

+0

http://stackoverflow.com/questions/927214/how-can-i-get-around-the-lack-of-a-finally-block-in-php – Peter

+1

В вашем случае, наконец, может работать, но я не знаю Не думайте, что вы используете его, это хорошая практика. Вы должны сделать все необходимые проверки перед использованием функции – JudgeProphet

+0

Итак, чтобы ответить на ваш вопрос: «Должен ли я использовать, наконец, для обработки« создать что-то, если он не существует »?», Я бы сказал «нет». См. Ниже, когда вы, возможно, захотите использовать наконец. – mika

ответ

29

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

$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 будет возвращать управление вызывающей функции.

Это может сделать это, если:

  • код, если ваш попробовать блок содержит тип исключения, которые вы не поймать
  • вы бросаете другое исключение в своем улове блоке
  • вашей попытка поймать или блок вызовы возвращают

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

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

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

+4

действительно понравился смысл примера. Спасибо :) –

+1

@Kamil Присмотритесь: здесь у вас есть оператор возврата в попытайтесь поймать блоки. Тем не менее, наконец, БУДУТ исполнено. – mika

+0

@mika поэтому thats разница! Очень большое спасибо. Вы, наконец, раскрыли тайну для меня :) – Kamil

4

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

С ручной (exceptions)

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

Это правильно. Но пример из OP является корректным (я задаюсь вопросом, не следует ли исключать класс исключений в скобках). – Tadeck

+0

Вот некоторые примеры того, как использовать «наконец»: https://wiki.php.net/rfc/finally из вики и http://athos.blogs.balabit.com/2011/02/try -catch-finally-in-php/from Athos, который кажется вам приятным :) –

+0

Alpha 5 был выпущен сегодня :) –

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

+0

«Что делать наконец» после успешного завершения блока «catch»? – Kamil

+0

@Kamil: Ответ редактируется. Надеюсь, я мог бы сделать это просто. –

+0

@Ted: полный ответ. Извините, если я ошибаюсь :( –

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, но работает одинаково.

 Смежные вопросы

  • Нет связанных вопросов^_^