What is the difference between the "Exception" of PHP?

5

It has several Exception defined in PHP, such as ErrorException PDOException Error ArithmeticError , etc ...

  • But what's the point of having so many exceptions like this?
  • Is there a difference between using one and the other?
asked by anonymous 24.05.2016 / 17:31

3 answers

5

The purpose is for you to be able to catch a specific exception.

All Exceptions in PHP are derived from the Exception class. When you capture Exception you are capturing any exception that occurs while executing the code.

Example:

 try{

      throw new InvalidArgumentException('Teste');

  } catch (Exception $e) {
          echo $e->getMessage();
  }

In this case, it is advantageous to do so if you really want to catch any exception that occurs in that portion of Try/catch .

Why use a specific exception?

But that is not always the case. Often, you need to know exactly what was the exception that occurred to perform a particular error handling. For example, if a function invokes a mathematical miscalculation exception and another points that the argument is not numeric, you may want to only use the exception, either it tells you the calculation error to inform a user log, whereas the you may want to leave it as a fatal error (because in PHP, when you throw an uncaught exception, you generate a fatal error).

Capturing Specific Exceptions

One point we have to make is that the Exceptions are varied because the problems are varied. So you use a specific Exception for each problem.

Consider for example a function where you have an argument that must be a array and that array must have 2 items. In this case, you will have to use an exception to indicate that it is not an array, and another to indicate an invalid size.

Example:

  function tem_que_ser_array_com_dois_itens($array) {
       if (! is_array($array)) {
            throw new \InvalidArgumentException('O argumento não é array');
       }

       if (count($array) !== 2) {
            throw new \LengthException("Tamanho do array é inválido. Deve ser apenas 2 itens');
       }
  }

So, to work with the possible exceptions thrown by this function, you can specify which exception you want to "catch" in catch if you did not want to catch any.

Example:

    try {

           tem_que_ser_um_array_com_dois_itens(1);
     } catch (InvalidArgumentException $e) {
          $e->getMessage();
     }

In the example above, only InvalidArgumentException is captured, because we want to treat an exception only if the argument is not valid. If the size is invalid, in the example above, the exception will be converted by PHP to a Fatal error, since it was not "caught".

If you used Exception in catch above, you would catch any exception generated by the function - Because all exception classes are derived from Exception , in PHP versions prior to version 7.

Multiple exception captures

However, this behavior may not be what you want. Then, you may want to handle both invalid argument and invalid argument exceptions. How could I solve this?

The solution is to use multiple catch . PHP allows this.

Example:

 try {
       tem_que_ser_array_com_dois_itens([1]);
  } catch (InvalidArgumentException $e) {

       echo 'Por favor, coloque um array';
  } catch (LengthException $e) {
       echo 'Seu array tá com tamanho errado';
  }

Responding simply to your questions:

  

But what is the purpose of having so many exceptions like this?

Each Exception represents an exception that may occur during the code. Exceptions can be invalid sizes, unexpected types, runtime errors. So there needs to be a specific Exception for each case, because if you used throw new Exception for everything, you would not know how to handle a specific exception and it would give you a lot of headaches.

In addition to using the PHP exceptions themselves, you can also create your own.

Example:

   class InvalidImageExtension extends \InvalidArgumentException {}

   if (! in_array($extensao, ['png', 'jpg', 'bmp']) {
         throw new InvalidImageExtension('Extensão inválida');
   }
  

Is there a difference between using one and the other?

As I said, you need an Exception to identify a specific problem. That is, it would not be arranged to throw the same exception to handle invalid argument and to handle an error when opening a file. Each case is a case.

Example that would not be legal:

try {

      if (is_array($array) {
           // Poderia ser UnexpectedValueException 
           // Ou InvalidArgumentException, se isso for argumento de uma função
           throw new Exception('Não é um array');
      }

      if (file_exists($file)) {
          // Poderia ser RunTimeException (erro no tempo de excecução)
          throw new Exception('Arquivo não existe');
      }
} catch (Exception $e) {

      // Se seu chefe pedir para você enviar um e-mail
      // Toda vez que não conseguir abrir um arquivo
      // Como você ia tratar isso? Fazendo IF?
     // Não seria melhor lançar e capturar uma exceção só para o arquivo não existente?

}

Show which Exception your function throws

I do not know if you usually use PHPDocumentor , but it's always good to note that some libraries specify exceptions that can be thrown in your code by comments like @throws . So, if you wish, you can capture the specific exception, rather than trying to guess.

Example:

 /**
 *
 * @param boolean $motor_ligado
 * @param string $modelo
 * @throws ProblemaNoMotorException
 * @throws VeiculoNaoVoadorException
 */
 function voar($motor_ligado = true, $modelo = 'aviao') 
 {
     if ($motor_ligado === false) {
          throw new ProblemaNoMotorException('Motor não está ligado');
     }

     if (! in_array($modelo, ['aviao', 'helicoptero']) {
        throw new VeiculoNaoVoadorException('Esse veículo não serve');
        // Ou UnexpectedValueException, por exemplo
     }
 }

What is rethrow?

I've seen this term being used in some frameworks, rethrow . In other words, "cast again". Sometimes you want to do a specific operation on catch , but you still need the Fatal Error generated by that exception.

In this case, you can throw the same exception after capturing it in catch .

See a useful example where I need to finalize a request in a client's webservice. If an error occurs, in addition to throwing the exception, I need to log it in a log.

So I can capture it, log it and launch it again:

 try {

    $db->finalizarNoWebserviceDoCliente();


 } catch (ServerException $e) {

    $db->logs()->registrarLog($e->getMessage());

    // Você lança a exceção novamente aqui
    throw $e;
 }
    
24.05.2016 / 17:52
2

Yes, there is a difference. When you use Exception in a try catch any type of error will drop into catch. If you specify another one as PDOException you are setting a specific error type to be caught by the catch. For example I use Laravel in development and when I want to catch errors coming from querys I use:

try{
  //meu código
} catch (\Illuminate\Database\QueryException $e) {

    return $e->getMessages();
}
    
24.05.2016 / 17:39
0

It all depends on the exception you want to grab.

By EX:

try {
    $PDO = new PDO('...');
}
catch( PDOException $Exception ) {
    echo 'Conecção à base de dados não foi bem sucedida';
}

Here you want to grab only this exception, letting the others do their natural throw, in the catch you can put up a 'Plan B' connection of another type if it fails. Note that in this case it will only be useful to grab this ( PDOException )

This is useful for eg within catch send a custom message depending on the exception, or do another action, until you define a new path of your sewing program the exception you want to catch in try catch .

    
24.05.2016 / 17:52