Diferencia entre revisiones de «PHP Control de erros»

De MediaWiki
Ir a la navegación Ir a la búsqueda
Línea 145: Línea 145:
 
: Vexamos un exemplo:
 
: Vexamos un exemplo:
  
::<syntaxhighlight lang="java" line enclose="div" highlight="2-10,6,34-37" >
+
::<syntaxhighlight lang="java" line enclose="div" highlight="2-9,19,33-36" >
 
         <?php
 
         <?php
 
             class ExcepcionNumerica extends Exception
 
             class ExcepcionNumerica extends Exception

Revisión del 08:53 21 mar 2017

Excepcións

  • Durante o desenvolvemento da aplicación imos atoparnos coa necesidade de controlar os erros que poidan darse nas chamadas ás diferentes funcións.
Isto pode levar a programar cunha estrutura de if - else moi 'anidada', que faga que o código sexa pouco lexible.
Podemos facer uso delas a partires da versión 5 de PHP.
  • A idea é moi simple: En caso de erro imos 'capturar' ou 'lanzar' unha excepción.
Unha excepción é un tipo de erro que pode darse na execución de programas. Normalmente son erros non controlados por nos nas liñas de programación, pero tamén podemos 'provocar' unha excepción enviando un texto e un código.


A sintaxe é moi sinxela:

 1 try {
 2 
 3   // Sentenzas a controlar
 4   if (condicion_a_controlar)
 5      throw new Exception('Mensaxe a enviar',1);   // Provocamos unha excepción. O control pasa a sección catch. Podemos enviar un texto e un dato numérico a sección catch (non é obrigatorio)
 6     
 7 
 8 }
 9 catch (Excepcion $e){
10   // Sentenzas a executar en caso de lanzarse a excepción
11 
12 }
  • Liña 5: En base a controlar algunha condición, podemos provocar unha excepción. Poderíamos lanzar a excepción se enviar nada á sección catch (throw Exception()), ou podemos enviar soamente un texto (throw Exception('Mensaxe a enviar')).
  • Liña 9: O obxecto $e pertence á clase Excepcion e dispón entre as súas propiedades e métodos:
  • $e->getMessage(); // Devolve a mensaxe da excepción. É o texto que enviamos na orde throw new Exception('texto',número)
  • $e->getCode(); // Devolve o código da excepción. É o número que enviamos na orde throw new Exception('texto',número)
  • Cando se produce a excepción, o control do programa vai a sección catch, deixando de executarse o resto de liñas do programa dentro da sección try.



  • A partires da versión PHP 5.5 podemos incorporar outra sección: finally.
Dita sección execútase sempre, haia ou non unha excepción e ao final de todo, despois de executar a última sentenza controlada ou despois de executar a sección catch se houbo unha excepción.
 1 try {
 2 
 3   // Sentenzas a controlar
 4   if (condicion_a_controlar)
 5      throw new Exception('Mensaxe a enviar');   
 6 
 7 }
 8 catch (Excepcion $e){
 9   // Sentenzas a executar en caso de lanzarse a excepción
10 
11 }
12 finally{
13   // Sentenzas que sempre se executan
14 }

Capturando os erros da funcións internas de PHP

  • Indicar que no caso de PHP 'tradicional' as funcións PHP non 'lanzan' excepcións, se non que 'avisan' con warnings, errors,...dependendo do nivel de erro a amosar, o cal está indicado na directiva display_error de php.ini.


 1         <?php
 2             set_error_handler(function () {
 3                 throw new Exception('Houbo un erro...');
 4             });
 5 
 6             try{
 7                 $array = array('uno','dos','tres');
 8                 echo $array[10];
 9                 
10             } 
11             catch (Exception $ex) {
12                 echo "Outro erro non controlado";
13                 echo $ex->getMessage(); // Amosará o enviado dende a función --> Houbo un erro...
14             }
15          ?>
  • Liñas 2-4: Definimos unha función que vai 'capturar' os erros que poidan lanzar as funcións de PHP, lanzando unha excepción da clase Exception que será capturada polo bloque catch (Exception $ex).


Se queremos volver a deixar a xestión de erros como estaba deberemos chamar á función restore_error_handler.

Xerarquía de excepcións

  • No control de excepcións temos unha xerarquía de clases que representan diferentes tipos de excepción.
Esta xerarquía ten unha estrutura de herdanza no que o pai de todas elas é a clase Excepcion (a vista na explicación anterior).
Esta clase (a clase Excepcion) ten coma vantaxe que vai poder capturar todas as excepcións que se poidan producir, pero terá como desvantaxe que non imos saber que tipo de excepción foi capturada (podemos ter unha idea polo código da excepción).


  • Para 'afinar' máis o tipo de erro que podemos capturar existen outras clases que derivan da clase Exception e que capturan un tipo específico de excepción. Desta forma podemos ou mandar unha mensaxe ao cliente ou ter diferentes sentenzas a executar en caso de producirse diferentes tipos de excepcións.


Php Exception 1.jpg
Imaxe obtida dende https://fossies.org/dox/php-5.2.17/classException.html



  • A partires da versións 7 de PHP aparece unha nova xerarquía de clases para capturar erros:
Php Exception 2.jpg
Máis información neste enlace


  • Polo tanto podemos 'capturar' e 'lanzar' varias excepcións:
 1 try {
 2 
 3   // Sentenzas a controlar
 4   if (condicion_a_controlar 1)
 5      throw new OutOfRangeException('Mensaxe a enviar',1);   // Provocamos unha excepción. O control pasa a sección catch. Podemos enviar un texto e un dato numérico a sección catch (non é obrigatorio)
 6 
 7   // Sentenzas a controlar
 8   if (condicion_a_controlar 2)
 9      throw new Exception('Mensaxe a enviar',1);   // Provocamos unha excepción. O control pasa a sección catch. Podemos enviar un texto e un dato numérico a sección catch (non é obrigatorio)
10     
11 
12 }
13 catch (OutOfRangeException $e){
14   // Sentenzas a executar en caso de lanzarse a excepción
15 }
16 catch (Exception $e){
17   // Sentenzas a executar en caso de lanzarse a excepción
18 }


Nota: Normalmente en todas as linguaxes a clase de excepción máis alta na xerarquía (neste caso Exception) ponse ao final de todo.


Excepcións definidas polo programador

  • Podemos crear as nosas propias excepcións creando unha clase que 'derive' da clase Exception.
Vexamos un exemplo:
 1         <?php
 2             class ExcepcionNumerica extends Exception
 3             {
 4               public function errorMessage() {
 5                    //error message
 6                   $errorMsg = $this->getMessage().'Soamente acéptanse valores numéricos.';
 7                   return $errorMsg;
 8               }        
 9             }
10         ?>
11         
12         
13         <?php
14             $a='cadea';
15             $array = array('uno','dos','tres'); 
16             try{
17                 
18                 if (!is_numeric($a)){
19                     throw new ExcepcionNumerica('Non é un número.');
20                 }
21                 
22                 // Supoñamos que queremos acceder ao elemento 10 do array
23                 $acceso = 10;
24                 if (count($array)<$acceso){ // Non podemos, xa que o array ten 3 elementos
25                     throw new OutOfRangeException('Acceso fora de rango no array...');
26                 }
27                 
28             } 
29             catch (OutOfRangeException $ex) {
30                 echo "Outro erro non controlado1<br />";
31                 echo $ex->getMessage() . ':' . $ex->getCode(); // Amosará o enviado dende o thow new
32             }
33             catch (ExcepcionNumerica $ex){
34                 echo "Outro erro non controlado2<br />";
35                 echo $ex->errorMessage() . ':' . $ex->getCode(); // Amosará o enviado dende o thow new máis o posto na clase => función errorMessage
36             }
37             catch (Exception $ex) {
38                 echo "Outro erro non controlado3<br />";
39                 echo $ex->getMessage() . ':' . $ex->getCode(); // Amosará o enviado dende o thow new
40             }
41         
42         ?>
  • Liñas 2-10: Definimos a nosa propia excepción.
  • Liña 6: Fixarse como podemos definir unha función propia (errorMessage) para enviar á sección catch unha mensaxe personalizada. Neste caso enviamos o texto que se indica na orde 'throw new' xunto cun texto.
  • Liña 20: Neste exemplo como non cumpre a condición de que $a sexa numérica lanzará a excepción.
  • Liñas 34-37: Capturamos a excepción personalizada.
  • Liña 36: Fixarse como facemos uso da función 'errorMessage()' definida por nos na clase ExcepcionNumerica.
  • Se no mesmo exemplo cambiades a liña 15 e dádeslle un valor numérico a $a, lanzará a excepción 'OutOfRangeException' (liña 26).


  • Como podedes ver somos nos os que decidimos o tipo de excepción a lanzar en base ao noso programa e condicións.






-- Ángel D. Fernández González -- (2016).