Verifica che un URL sia valido (dal client soap php)
-
05-07-2019 - |
Domanda
Sto scrivendo un'app Web che consentirà all'utente di specificare un URL per un SoapClient. Volevo confermare che php può connettersi al client quando l'utente invia un modulo. Potrei farlo tramite try catch o set_error_handler (o una combinazione dei due). Tuttavia sembra che questo non sia possibile per errori fatali. C'è un modo per convincere SoapClent a testare un URL che non genererà un errore irreversibile?
Fatal error: SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://example.com/wibble'
Voglio che contrassegni un errore poiché l'URL non esiste, ma vorrei essere in grado di rilevarlo.
Altrimenti suppongo di poter provare a scaricare e convalidare l'URL da solo, ma avrei pensato che sarebbe stato possibile farlo da SoapClient.
Questo dovrebbe essere un errore fatale?
Modifica
Dopo aver letto la risposta di rogeriopvl, ribadisco che avrei dovuto dire che avevo provato l'opzione "eccezioni" al costruttore soapclient e (nella disperazione) la funzione use-soap-error-handler.
Soluzione
Stai usando xdebug? Secondo questa segnalazione e discussione sui bug di PHP , il problema è stato risolto almeno da PHP 5.1, ma questo bug xdebug fa un errore con "errore fatale nelle conversioni di eccezione" in un modo in cui l'eccezione non viene generata e l'errore fatale "perde".
Posso riprodurlo localmente, con xdebug abilitato:
try {
$soapClient = new SoapClient('http://www.example.com');
}
catch(Exception $e) {
$exceptionMessage = t($e->getMessage());
print_r($exceptionMessage);
}
Questo mi dà l'errore fatale che hai descritto, senza nemmeno inserire la clausola catch:
Fatal error: SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://www.example.com'
Funziona se disabilito xdebug subito prima della chiamata:
xdebug_disable();
try {
$soapClient = new SoapClient('http://www.example.com');
}
catch(Exception $e) {
$exceptionMessage = t($e->getMessage());
print_r($exceptionMessage);
}
Questo innesca l'eccezione come previsto e ottengo un oggetto SoapFault corretto nella clausola catch con un messaggio di:
SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://www.example.com'
Quindi, in sostanza, le eccezioni funzionano come pubblicizzato. Se non funzionano nel tuo caso, potresti riscontrare il bug xdebug o un problema simile con un altro componente di terze parti.
Altri suggerimenti
Citando Documentazione SoapClient :
L'opzione eccezioni è un valore booleano che definisce se gli errori soap generano eccezioni di tipo SoapFault.
Quindi dovresti provare qualcosa del tipo:
$client = new SoapClient("some.wsdl", array('exceptions' => TRUE));
In questo modo verranno generate SoapFault consentendoti di catturarli .
Vedi: http://bugs.xdebug.org/view.php?id= 249
Possibile soluzione:
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();
}
}
potresti provare a fare una richiesta curl o fsockopen per verificare che l'URL sia valido.
Per tua informazione, sto usando SoapClient con PHPUnit per testare i servizi Web remoti e ho riscontrato lo stesso problema!
- quando si utilizza una vecchia versione di PHPUnit (3.3.x) come terza parte, crash di phpunit
- quando si utilizza la versione corrente di PHPUnit (3.4.6) come terza parte, phpunit visualizza " RuntimeException " ;.
Ecco il mio primo metodo di prova:
public function testUnavailableURL() { $client = new SoapClient("http://wrong.URI"); }
Ecco il primo risultato di PHPUnit:
There was 1 error: 1) MyTestCase::testUnavailableURL RuntimeException: FAILURES!
Ecco il mio secondo metodo di prova:
public function testUnavailableURL() { try { $client = @new SoapClient("http://wrong.URI"); } catch (SoapFault $fault) { print "SOAP Fault: (faultcode: {$fault->faultcode}, faultstring: {$fault->faultstring})"; } }
Ecco il secondo risultato del test 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: ho trovato un biglietto phpunit su questo argomento: ticket 417