Pergunta

Eu estou escrevendo uma aplicação web que permitirá que o usuário especifique um URL para um SoapClient. Eu queria validar que php pode ligar para o cliente quando o usuário envia um formulário. I thouhgt eu poderia fazer isso via try catch ou set_error_handler (ou alguma combinação dos dois). No entanto, parece que isso não é possível para erros fatais. Existe uma maneira de obter SoapClent para testar um URL que não irá lançar um erro irrecuperável?

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

Eu quero que ele sinalizar um erro como o URL não existe, mas eu gostaria de ser capaz de pegá-lo.

Caso contrário, eu acho que eu poderia tentar fazer o download e validar o URL mim, mas eu teria pensado que seria possível fazê-lo a partir do SoapClient.

Se este for um erro fatal?

Editar

Depois de ler a resposta do rogeriopvl I reaslise que eu deveria ter dito que eu tinha tentado a opção 'exceções' para o construtor soapclient e (em desespero) a função uso de sabão-error-manipulador.

Foi útil?

Solução

Você está usando xdebug? De acordo com a esta PHP relatório de bug e discussão , o problema foi resolvido, pelo menos uma vez PHP 5.1, mas messes esta xdebug bugs com 'erro fatal para conversões de exceção' em uma forma que a exceção não é gerada e o erro fatal 'vazamentos através'.

Eu posso reproduzir isso localmente, com xdebug ativado:

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

Isto dá-me o erro fatal que você descreveu, sem sequer entrar na cláusula catch:

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

Ele funciona se eu desativar xdebug direito antes da chamada:

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

Isso desencadeia a exceção como esperado, e eu recebo um objeto SoapFault adequada na cláusula catch com uma mensagem de:

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

Então, basicamente exceções funcionam como anunciado. Se eles não funcionam no seu caso, você pode encontrar o bug xdebug, ou talvez um problema semelhante com outro componente 3o partido.

Outras dicas

SoapClient documentação :

A opção exceções é um valor booleano que define se os erros de sabão lançar exceções do tipo SoapFault.

Assim que você deve tentar algo como:

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

Desta forma vai jogar SoapFault exceções permitindo que você pegá-los .

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

Solução possível:

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

você poderia tentar e fazer uma onda ou pedido fsockopen para verificar o URL é válido.

Para sua informação, eu estou usando SoapClient com PHPUnit para testar WebServices remotos e tem o mesmo problema!

  • ao usar uma versão antiga PHPUnit (3.3.x) como terceiros, acidente phpunit
  • Ao usar a versão atual do PHPUnit (3.4.6) como terceiros, display phpunit "RuntimeException".

Aqui é o meu primeiro método de teste:

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

Aqui está PHPUnit primeiro resultado:

There was 1 error:

1) MyTestCase::testUnavailableURL
RuntimeException: 


FAILURES!

Aqui é o meu segundo método de teste:

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

Aqui está PHPUnit segundo resultado do teste:

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: eu encontrei um bilhete phpunit sobre este assunto: ticket 417

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top