2009-11-18 16 views
18

En mi aplicación estoy cargando xml desde url para poder analizarlo. Pero a veces esta url puede no ser válida. En este caso, necesito manejar los errores. Tengo el siguiente código:PHP DOMDocument error handling

$xdoc = new DOMDocument(); 
try{ 
    $xdoc->load($url); // This line causes Warning: DOMDocument::load(...) 
        // [domdocument.load]: failed to open stream: 
        // HTTP request failed! HTTP/1.1 404 Not Found in ... 
} catch (Exception $e) { 
    $xdoc = null; 
} 

if($xdoc == null){ 
    // Handle 
} else { 
    // Proceed 
} 

Sé que probablemente haciendo mal, pero lo que es una manera correcta de manejar este tipo de excepciones? No quiero ver mensajes de error en mi página.

El manual para DOMDocument :: load() dice:

Si una cadena vacía se pasa como el nombre de archivo o un archivo vacío se nombra, se generará una advertencia . Esta advertencia no es generada por libxml y no se puede manejar usando las funciones de manejo de error de libxml.

Pero no hay información sobre cómo manejarlo.

Gracias.

Respuesta

32

Según lo que puedo deducir del documentation, el manejo de las advertencias emitidas por este método es complicado porque no están generadas por la extensión libxml y por lo tanto no pueden ser manejadas por libxml_get_last_error(). Se podría utilizar el operador de supresión de errores y comprobar el valor de retorno para false ...

if (@$xdoc->load($url) === false) 
    // ...handle it 

... o registrarse an error handler which throws an exception on error:

function exception_error_handler($errno, $errstr, $errfile, $errline) { 
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline); 
} 

y luego atraparlo.

+0

Gracias por la supresión de errores del operador. –

+1

También puedes usar libxml_use_internal_errors (false) para suprimir el error y verificar si hay errores en los datos – Ligemer

2

De php.net

Si una cadena vacía se pasa como el nombre del archivo o un archivo vacío es nombrado, se generará una advertencia . Esta advertencia no es generada por libxml y no se puede manejar usando las funciones de manejo de error de libxml.

En su entorno de producción, no debería mostrar errores al usuario. Ellos no tienen que verlos por lo que teniendo en cuenta que puede utilizar ...

$xdoc = new DOMDocument(); 
if ($xdoc->load($url)) { 
    // valid 
} 
else { 
    // invalid 
} 
7
set_error_handler(function($number, $error){ 
    if (preg_match('/^DOMDocument::loadXML\(\): (.+)$/', $error, $m) === 1) { 
     throw new Exception($m[1]); 
    } 
}); 

$xml = new DOMDocument(); 
$xml->loadXML($xmlData); 

restore_error_handler(); 

que funciona para mí en PHP 5.3. Pero si no está usando loadXML, es posible que tenga que hacer algunas modificaciones.

+1

¡Increíble en esta publicación es demasiado alto! – Sebas

+0

Estoy usando loadXML, pero todavía no ayuda ... :( –

+0

@Znarkus Creo que la solución actual contiene un pequeño error. Para que este código no tenga efectos secundarios, el controlador de error personalizado debe aparecer stack * independientemente * de si 'loadXML()' se completó sin errores. Actualmente, si 'loadXML()' emite un error que es interceptado por el manejador de error personalizado, 'restore_error_handler();' nunca será invocado. El manejador de error personalizado permanecer en vigencia, lo cual es casi seguro que no queremos. Para solucionarlo, sugiero agregar una llamada a 'restore_error_handler();' dentro de la declaración 'if' del cierre, justo antes de arrojar la excepción. – Nate

4

Para desactivar tirar errores:

$internal_errors = libxml_use_internal_errors(true); 

$dom = new DOMDocument(); 
// etc... 

libxml_use_internal_errors($internal_errors); 
+4

Lea el manual Esta advertencia no es generada por libxml y no se puede manejar usando las funciones de manejo de errores de libxml. –

+1

Funciona perfectamente, cuando se usa con 'libxml_get_last_error()'. – BurninLeo

0

Para mí, lo siguiente hizo el truco

$feed = new DOMDocument(); 
$res= @$feed->load('http://www.astrology.com/horoscopes/daily-extended.rss'); 
if($res==1){ 
      //do sth 
      }