Я использую 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); }
Затем в руководстве написано:
В интересах кого-то, кто раньше не сталкивался с блоками, ключевое различие между ними и нормальным кодом после блока 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, вы еще не можете использовать finally
.
Из руководства ( исключения )
В 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'; ?>
Наконец, означает, что вы хотите сделать Наконец.
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 }
Как вы можете видеть, таким образом, независимо от того, что произойдет, временный файл будет удален правильно.
Если мы будем эмулировать предложение finally
в старой версии PHP, мы должны написать что-то вроде этого:
// start finally catch(Exception $ex) { } if($tmp_name) unlink($tmp_name); if( isset($ex) ) throw $ex; // end finally
Обратите внимание, что исключение было повторно выбрано, если блок catch
поймал что-то. Это неясно, как finally
версия, но работает одинаково.