Pregunta

Estoy escribiendo una aplicación web que permitirá al usuario especificar una URL para un SoapClient. Quería validar que PHP puede conectarse al cliente cuando el usuario envía un formulario. Yo 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 arroje un error irrecuperable?

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

Quiero que marque un error porque la URL no existe, pero me gustaría poder detectarlo.

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

¿Debería ser un error fatal?

Editar

Después de leer la respuesta de rogeriopvl, reitero que debería haber dicho que probé la opción de 'excepciones' al constructor de jabón y (en desesperación) la función de uso de jabón de errores.

¿Fue útil?

Solución

¿Estás usando xdebug? Según este informe y discusión de errores de PHP , el problema se ha solucionado al menos desde PHP 5.1, pero este error de xdebug se mete con 'error fatal a conversiones de excepción' en una forma de que la excepción no se genere y el error fatal "se filtre".

Puedo reproducir esto localmente, con xdebug habilitado:

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 describiste, sin siquiera ingresar 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 activa la excepción como se esperaba, y obtengo 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 las 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.

Otros consejos

Cotizando documentación de SoapClient :

  

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

Así que deberías probar algo como:

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

De esta manera, se lanzarán las excepciones SoapFault que le permiten capturarlas .

Consulte: 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();
     }
   }

puedes probar y hacer una solicitud de curl o fsockopen para comprobar que la URL es válida.

Para su información, estoy usando SoapClient con PHPUnit para probar los servicios web remotos y tengo el mismo problema.

  • cuando se utiliza una versión antigua de PHPUnit (3.3.x) como tercero, phpunit crash
  • al usar la versión actual de PHPUnit (3.4.6) como tercero, phpunit display " RuntimeException " ;.

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

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

Aquí está el primer resultado de PHPUnit:

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í está el resultado de la segunda prueba de PHPUnit:

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: encontré un ticket de phpunit sobre este tema: ticket 417

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top