Как эффективно использовать try … catch блоки в PHP

Я использую try..catch блоки в моем PHP-коде, но я не уверен, правильно ли я их использовал.

Например, некоторые из моего кода выглядят так:

try { $tableAresults = $dbHandler->doSomethingWithTableA(); $tableBresults = $dbHandler->doSomethingElseWithTableB(); } catch (Exception $e) { return $e; } 

Поэтому я группирую несколько операций с базами данных в одном блоке try / catch, потому что, если какое-либо исключение возникает в любой транзакции, я смогу справиться с этим.

Я делаю так, потому что считаю, что это более читаемо и эффективно, чем:

  try { $tableAresults = $dbHandler->doSomethingWithTableA(); } catch (Exception $e) { return $e; } try { $tableBresults = $dbHandler->doSomethingWithTableB(); } catch (Exception $e) { return $e; } 

Хотя, я не уверен, что то, что я делаю, – это хорошая практика или просто ленивый способ поймать исключения.

Мое предположение заключается в том, что только если для исключения требуется специальная обработка, у него должен быть свой собственный блок try / catch, иначе группировка их в том же try / catch должна быть в порядке.

Итак, мои вопросы:

Есть ли преимущество использования блоков try / catch в транзакции базы данных? или я могу по-прежнему группировать несколько транзакций базы данных в одном блоке try / catch без каких-либо проблем?

Можно ли встраивать блоки try / catch? Благодаря!

РЕДАКТИРОВАТЬ

Оператор return был предназначен только для демонстрационных целей, но я также использую return в catch() потому что я делаю запрос AJAX к этому методу, и Javascript ожидает объект JSON, а затем, если возникает исключение, я возвращаю пустой JSON-кодированный массив. Я просто подумал, что это не добавит никакой ценности, чтобы вставить конкретный код в мой пример.

Важная заметка

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


Пока вы намереваетесь делать то же самое, независимо от того, какой оператор в блоке try генерирует исключение, то, безусловно, лучше использовать один try / catch . Например:

 function createCar() { try { install_engine(); install_brakes(); } catch (Exception $e) { die("I could not create a car"); } } 

Несколько блоков try / catch полезны, если вы можете и собираетесь обрабатывать сбой способом, соответствующим тому, что именно вызвало его.

 function makeCocktail() { try { pour_ingredients(); stir(); } catch (Exception $e) { die("I could not make you a cocktail"); } try { put_decorative_umbrella(); } catch (Exception $e) { echo "We 're out of umbrellas, but the drink itself is fine" } } 

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

 try{ $tableAresults = $dbHandler->doSomethingWithTableA(); if (!tableAresults) throw new Exception('Problem with tableAresults'); $tableBresults = $dbHandler->doSomethingElseWithTableB(); if (!tableBresults) throw new Exception('Problem with tableBresults'); } catch (Exception $e) { echo $e->getMessage(); } 

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

Однако я бы сказал, что возвращение исключения делает лишь ограниченный смысл. Возвращаемое значение функции должно быть ожидаемым результатом какого-либо действия, а не исключения. Если вам нужно отреагировать на исключение в области вызова, то либо не поймайте исключение здесь внутри вашей функции, а в области вызова или повторно выбросите исключение для последующей обработки после выполнения некоторых протоколов отладки и т. П.

Когда генерируется исключение, выполнение немедленно приостанавливается и продолжается в блоке catch{} . Это означает, что если вы поместите вызовы базы данных в один и тот же try{} block и $tableAresults = $dbHandler->doSomethingWithTableA(); выдает исключение, $tableBresults = $dbHandler->doSomethingElseWithTableB(); не произойдет. Второй вариант: $tableBresults = $dbHandler->doSomethingElseWithTableB(); будет по-прежнему происходить, так как это после блока catch{} , когда выполнение возобновлено.

Для каждой ситуации нет идеального варианта; если вы хотите, чтобы вторая операция продолжалась независимо, тогда вы должны использовать два блока. Если приемлемо (или желательно), чтобы вторая операция не выполнялась, вы должны использовать только одну.

Это более читаемый один блок catch catch. Если это важно, укажите ошибку, я рекомендую настроить свои Исключения.

 try { $tableAresults = $dbHandler->doSomethingWithTableA(); $tableBresults = $dbHandler->doSomethingElseWithTableB(); } catch (TableAException $e){ throw $e; } catch (Exception $e) { throw $e; } 

в одном блоке catch try вы можете сделать все, что лучше всего поймать ошибку в разных блоках catch, если вы хотите, чтобы они показывали со своим сообщением о конкретных ошибках.

 try { $tableAresults = $dbHandler->doSomethingWithTableA(); if(!tableAresults) { throw new Exception('Problem with tableAresults'); } $tableBresults = $dbHandler->doSomethingElseWithTableB(); if(!tableBresults) { throw new Exception('Problem with tableBresults'); } } catch (Exception $e) { echo $e->getMessage(); } 

Нет никакой проблемы, чтобы написать несколько строк выполнения с одним блоком захвата try, как показано ниже.

 try{ install_engine(); install_break(); } catch(Exception $e){ show_exception($e->getMessage()); } 

В тот момент, когда любое изъятие происходит либо в функции install_engine либо в функции install_break элемент управления будет передан функции catch. Еще одна рекомендация – правильно использовать свое исключение. Это означает, что вместо написания die('Message') всегда целесообразно иметь процесс исключения. Вы можете подумать об использовании функции die() при обработке ошибок, но не в обработке исключений.

Когда вы должны использовать несколько блоков catch try, вы можете подумать о нескольких блоках catch try, если вы хотите, чтобы исключение из другого блока кода отображало различный тип исключения или вы пытаетесь выбросить любое исключение из вашего блока catch, как показано ниже:

 try{ install_engine(); install_break(); } catch(Exception $e){ show_exception($e->getMessage()); } try{ install_body(); paint_body(); install_interiour(); } catch(Exception $e){ throw new exception('Body Makeover faield') } 

Для более подробной информации о том, как вы можете использовать блок catch try в разных случаях, вы можете обратиться к моему блогу на PHP Try Catch