Como usar eficientemente ... catch blocks in PHP

Tenho usado o try..catch blocks in my PHP code, but i'm not sure if i've been using them correctly.

Por exemplo, alguns dos meus códigos parecem:
 try {
      $tableAresults = $dbHandler->doSomethingWithTableA();
      $tableBresults = $dbHandler->doSomethingElseWithTableB();
 } catch (Exception $e) {
      return $e;
 }
Então estou agrupando várias operações de banco de dados no mesmo bloco de tentativa/captura porque se alguma exceção ocorrer em qualquer uma das transações, eu serei capaz de lidar com isso.

Estou a fazê - lo assim porque acho que é mais legível e eficiente do que:
 try {
       $tableAresults = $dbHandler->doSomethingWithTableA();
 } catch (Exception $e) {
       return $e;
 }
 try {
       $tableBresults = $dbHandler->doSomethingWithTableB();
 } catch (Exception $e) {
       return $e;
 }
Apesar de não ter a certeza se o que sou fazer é uma boa prática ou apenas uma forma preguiçosa de pegar exceções.

a minha suposição é que só se uma excepção requer um manuseamento especial, deve ter o seu próprio bloco de tentativa/captura, caso contrário agrupá-los na mesma tentativa/captura deve estar ok.

A minha pergunta é: Existe alguma vantagem em utilizar blocos de tentativa / captura por transacção na base de dados? ou ainda posso agrupar várias transações de banco de dados no mesmo bloco de tentativa / captura sem nenhum problema?

Não faz mal fazer ninho. tentar / apanhar blocos? Obrigado!

EDITAR

a declaração de retorno foi principalmente para fins de demonstração, mas eu também estou usando retornos em {[[2]} porque eu estou fazendo um pedido AJAX para esse método, e Javascript está esperando um objeto JSON, então se uma exceção ocorrer eu retornar um array codificado JSON vazio. Eu só pensei que não iria adicionar qualquer valor para colocar um código específico no meu exemplo.

Author: Mohd Abdul Mujib, 2013-07-09

8 answers

Nota Importante

A seguinte discussão assume que estamos falando de código estruturado como no exemplo acima: não importa qual alternativa é escolhida, uma exceção fará com que o método logicamente pare de fazer o que quer que fosse no meio de.


Desde que tenciones fazer a mesma coisa, independentemente da declaração no bloco que abre uma excepção, então é melhor usar um único.try/catch. Para exemplo:
function createCar()
{
    try {
      install_engine();
      install_brakes();
    } catch (Exception $e) {
        die("I could not create a car");
    }
}

Múltiplo try/catch blocos são úteis se você pode e pretende lidar com o fracasso de uma forma específica para o que exatamente causou isso.

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"
    }
}
 81
Author: Jon, 2013-07-09 13:44:06
Para a posteridade, a resposta talvez seja tarde demais.Você deve verificar o valor de retorno da variável e lançar uma exceção. Nesse caso, você tem certeza de que o programa vai saltar de onde a exceção está sendo levantada para o bloco de captura. Encontra lá em baixo.
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();

}
 18
Author: kodepet, 2014-10-20 23:31:47

Não há nenhuma razão contra usar um único bloco para várias operações, uma vez que qualquer exceção lançada impedirá a execução de outras operações após a falha. Pelo menos desde que você possa concluir qual operação falhou da exceção capturada. Isto é, desde que esteja tudo bem se algumas operações não forem processadas .

No entanto, eu diria que devolver a excepção faz apenas um sentido limitado. Um valor de retorno de uma função deve ser o resultado esperado de alguns acção, não excepção. Se você precisar reagir sobre a exceção no escopo de chamada, então ou não pegar a exceção aqui dentro de sua função, mas no escopo de chamada ou re-jogar a exceção para o processamento posterior, depois de ter feito algum registro de depuração e afins.
 7
Author: arkascha, 2013-07-09 13:45:28

Quando uma excepção é lançada, a execução é imediatamente interrompida e continua no bloco catch{}. Isto significa que, se você colocar as chamadas da base de dados no mesmo bloco try{} e $tableAresults = $dbHandler->doSomethingWithTableA(); lançar uma exceção, $tableBresults = $dbHandler->doSomethingElseWithTableB(); não irá ocorrer. Com a sua segunda opção, $tableBresults = $dbHandler->doSomethingElseWithTableB(); ainda irá ocorrer uma vez que é após o bloco catch{}, quando a execução foi retomada.

Não existe uma opção ideal para cada situação; se quiser que a segunda operação continue independentemente, então deve usar dois blocos. Se for aceitável (ou desejável) para que a segunda operação não ocorra, então você deve usar apenas um.

 5
Author: IanPudney, 2013-07-09 13:38:14
É mais legível uma única tentativa de bloqueio. Se é importante identificar um tipo de erro eu recomendo personalizar suas exceções.
try {
  $tableAresults = $dbHandler->doSomethingWithTableA();
  $tableBresults = $dbHandler->doSomethingElseWithTableB();
} catch (TableAException $e){
  throw $e;
} catch (Exception $e) {
  throw $e;
}
 5
Author: zongo, 2016-10-19 19:24:43

Num único bloco de captura tente você pode fazer tudo o que a melhor prática é apanhar o erro em diferentes blocos de captura Se quiser que eles mostrem com a sua própria mensagem para erros específicos.

 0
Author: Amar Agrawal, 2013-07-09 13:39:03
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();
}
 0
Author: nitin kumar maurya, 2016-10-19 12:57:07
Não há nenhum problema em escrever várias linhas de execução com um único bloco de captura como abaixo
try{
install_engine();
install_break();
}
catch(Exception $e){
show_exception($e->getMessage());
}

No momento em que qualquer execução ocorrer quer na função install_engine quer na função install_break, o controlo será passado para a função de captura. Mais uma recomendação é comer bem a sua excepção. O que significa que em vez de escrever die('Message') é sempre aconselhável ter o processo de exceção corretamente. Pode pensar em usar a função die() no tratamento de erros, mas não em excepção. tratamento.

Quando você deve usar vários tente bloquear Poderá pensar em várias tentativas de bloqueio de captura Se quiser que a excepção do bloco de código diferente mostre um tipo diferente de excepção ou se estiver a tentar abrir qualquer excepção do seu bloco de captura como em baixo:

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')
}

Para mais detalhes sobre como você pode usar tente catch block em diferentes casos você pode se referir ao meu blog em PHP tente Catch

 -1
Author: Ankur Kumar Singh, 2017-03-02 23:19:53