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