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


Я использую try..поймайте блоки в моем 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? Спасибо!

EDIT

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

8 69

8 ответов:

важное замечание

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


пока вы намерены делать то же самое независимо от того, какой заявление в 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{} блок а $tableAresults = $dbHandler->doSomethingWithTableA(); выдает исключение, $tableBresults = $dbHandler->doSomethingElseWithTableB(); не будет происходить. С вашим вторым вариантом, $tableBresults = $dbHandler->doSomethingElseWithTableB(); все равно произойдет, так как это после catch{} блок, когда выполнение возобновился.

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

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

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

в одном блоке try catch вы можете сделать все, что лучше всего, чтобы поймать ошибку в другом блоке 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 catch, как показано ниже

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

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

когда вы должны использовать несколько попыток поймать блок Вы можете подумать о нескольких блоках try catch, если вы хотите, чтобы исключение другого блока кода отображало другой тип исключения, или вы пытаетесь выбросить любое исключение из своего блока 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')
}

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