2009-09-10 18 views
13

Estoy escribiendo una aplicación web que permitirá al usuario especificar una URL para un cliente de SoapClient. Quería validar que php puede conectarse con el cliente cuando el usuario envía un formulario. Creo que podría hacer esto a través de try catch o set_error_handler (o alguna combinación de los dos). Sin embargo, parece que esto no es posible para errores fatales. ¿Hay alguna manera de que SoapClent pruebe una URL que no arrojará un error irrecuperable?Comprobando que una URL es válida (desde el cliente de php soap)

Fatal error: SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://example.com/wibble' 

yo quiero que la bandera de un error que la URL no existe, pero me gustaría ser capaz de atraparlo.

De lo contrario, supongo que podría intentar descargar y validar la URL yo mismo, pero habría pensado que sería posible hacerlo desde el SoapClient.

¿Debería ser un error fatal?

Editar

Después de leer la respuesta de rogeriopvl I reaslise que debería haber dicho que había intentado la opción 'excepciones' al constructor SoapClient y (en la desesperación) la función de uso de jabón controlador de errores.

Respuesta

22

¿Estás utilizando xdebug? Según this PHP bug report and discussion, el problema se ha solucionado al menos desde PHP 5.1, pero this xdebug bug se mezcla con 'errores fatales para convertir excepciones' de forma que la excepción no se genera y el error fatal 'se filtra'.

puedo reproducir este local, con Xdebug permitido:

try { 
    $soapClient = new SoapClient('http://www.example.com'); 
} 
catch(Exception $e) { 
    $exceptionMessage = t($e->getMessage()); 
    print_r($exceptionMessage); 
} 

Esto me da el error fatal que ha descrito, sin ni siquiera entrar en la cláusula catch:

Fatal error: SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://www.example.com' 

Funciona si desactivo xdebug justo antes de la llamada:

xdebug_disable(); 
try { 
    $soapClient = new SoapClient('http://www.example.com'); 
} 
catch(Exception $e) { 
    $exceptionMessage = t($e->getMessage()); 
    print_r($exceptionMessage); 
} 

Esto desencadena la excepción como se esperaba, y obtener un objeto SoapFault adecuado en la cláusula catch con un mensaje de:

SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://www.example.com' 

Así que, básicamente excepciones funcionan como se anuncia. Si no funcionan en su caso, puede encontrar el error xdebug, o tal vez un problema similar con otro componente de terceros.

+0

xdebug tiene errores. Esa es una nueva para mí, gracias. –

+4

Era nuevo para mí también: no hay muchas cosas más molestas que los errores de búsqueda causados ​​por el propio depurador:/ –

+1

Era un error de Xdebug, pero lo he solucionado recientemente. Aunque no es parte de un lanzamiento. – Derick

1

Citando SoapClient documentation:

La opción de excepciones es un valor booleano que define si los errores de jabón lanzan excepciones de tipo SoapFault.

Por lo que debe intentar algo como:

$client = new SoapClient("some.wsdl", array('exceptions' => TRUE)); 

De esta manera lanzará SoapFault excepciones que permiten que para su captura.

+0

lo he intentado, no funcionó, debería haber puesto en la pregunta, mi mal, lo actualizaré. –

0

puede intentar hacer una solicitud curl o fsockopen para comprobar que la URL sea válida.

+0

Esto comprobará que se puede obtener algo de la URL, pero no comprobará si se trata de un archivo WSDL real. –

0

Para su información, estoy usando SoapClient con PHPUnit para probar WebServices remotos y tengo el mismo problema!

  • si usa una versión antigua PHPUnit (3.3.x) en calidad de tercero, PHPUnit accidente
  • cuando se utiliza la versión actual de PHPUnit (3.4.6) en calidad de tercero, pantalla PHPUnit "RuntimeException".

Aquí es mi primer método de prueba:

 
public function testUnavailableURL() { 
    $client = new SoapClient("http://wrong.URI"); 
} 

Aquí se PHPUnit primer resultado:

 
There was 1 error: 

1) MyTestCase::testUnavailableURL 
RuntimeException: 


FAILURES! 

Aquí está mi segundo método de prueba:

 
public function testUnavailableURL() { 
     try { 
      $client = @new SoapClient("http://wrong.URI"); 
     } catch (SoapFault $fault) { 
      print "SOAP Fault: (faultcode: {$fault->faultcode}, faultstring: {$fault->faultstring})"; 
     } 
} 

Aquí es PHPUnit resultado de la segunda prueba:

 
PHPUnit 3.4.6 by Sebastian Bergmann. 

.SOAP Fault: (faultcode: WSDL, faultstring: SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://wrong.URI' : failed to load external entity "http://wrong.URI" 
)... 

Time: 3 seconds, Memory: 4.25Mb 

OK 

NB: i encontrado un billete de PHPUnit sobre este tema: ticket 417

1

Ver: http://bugs.xdebug.org/view.php?id=249

Posible solución:

Index: trunk/www/sites/all/libraries/classes/defaqtoSoapClient.class.php 
=================================================================== 
--- classes/defaqtoSoapClient.class.php 
+++ classes/defaqtoSoapClient.class.php 
@@ -31,10 +31,23 @@ 

    try { 
+  // xdebug and soap exception handling interfere with each other here 
+  // so disable xdebug if it is on - just for this call 
+  if (function_exists('xdebug_disable')) { 
+   xdebug_disable(); 
+  } 
     //Create the SoapClient instance 
     parent::__construct($wsdl, $options); 
    } 
    catch(Exception $parent_class_construct_exception) { 
+  if (function_exists('xdebug_enable')) { 
+   xdebug_enable(); 
+  } 
     // Throw an exception an say that the SOAP client initialisation is failed 
     throw $parent_class_construct_exception; 
+ } 
+ if (function_exists('xdebug_enable')) { 
+  xdebug_enable(); 
    } 
    } 
+0

Una mejor solución ya es parte del repositorio Xdebug github. – Derick

Cuestiones relacionadas