Проверка URL-адреса действительна (от клиента php soap)

Я пишу веб-приложение, которое позволит пользователю указать URL-адрес для SoapClient. Я хотел бы подтвердить, что php может подключаться к клиенту, когда пользователь отправляет форму. Я бы сделал это через try catch или set_error_handler (или некоторую комбинацию из двух). Однако похоже, что это невозможно для фатальных ошибок. Есть ли способ заставить SoapClent протестировать URL-адрес, который не будет вызывать неустранимую ошибку?

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

Я хочу, чтобы он указывал ошибку, поскольку URL-адрес не существует, но я хотел бы уловить его.

В противном случае, я полагаю, я мог бы попробовать загрузить и проверить URL-адрес сам, но я бы подумал, что это возможно сделать из SoapClient.

Должно ли это быть фатальной ошибкой?

Edit

После прочтения rogeriopvl ответа я расскажу, что я должен был сказать, что я попробовал опцию "exceptions" для конструктора soapclient и (в отчаянии) функцию обработчика-мыльной ошибки.

Ответы

Ответ 1

Вы используете xdebug? Согласно этот отчет об ошибках PHP и обсуждение, проблема была исправлена ​​по крайней мере с PHP 5.1, но эта ошибка xdebug помещается с "фатальной ошибкой в ​​преобразования исключений" таким образом, что исключение не генерируется, а фатальная ошибка "просачивается".

Я могу воспроизвести это локально, с включенным xdebug:

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

Это дает мне фатальную ошибку, о которой вы описали, даже не вставляя предложение catch:

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

Он работает, если я отключу xdebug прямо перед вызовом:

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

Это вызывает исключение, как ожидалось, и я получаю надлежащий объект SoapFault в предложении catch с сообщением:

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

Так что в основном исключения работают как рекламируемые. Если они не работают в вашем случае, вы можете столкнуться с ошибкой xdebug или, возможно, с аналогичной проблемой с другим сторонним компонентом.

Ответ 2

Цитата Документация SoapClient:

Параметр exceptions - это логическое значение, определяющее, генерируют ли мыльные ошибки исключения типа SoapFault.

Итак, вы должны попробовать что-то вроде:

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

Этот способ будет генерировать SoapFault исключения, позволяющие их поймать.

Ответ 3

Смотрите: http://bugs.xdebug.org/view.php?id=249

Возможное решение:

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

Ответ 4

вы можете попробовать и выполнить запрос curl или fsockopen для проверки правильности URL.

Ответ 5

Для вашей информации я использую SoapClient с PHPUnit для тестирования удаленных WebServices и получил ту же проблему!

  • при использовании старой версии PHPUnit (3.3.x) в качестве третьей стороны, сбой phpunit
  • при использовании текущей версии PHPUnit (3.4.6) в качестве третьей стороны, phpunit display "RuntimeException".

Вот мой первый метод тестирования:

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

Вот первый результат PHPUnit:

There was 1 error:

1) MyTestCase::testUnavailableURL
RuntimeException: 


FAILURES!

Вот мой второй метод тестирования:

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

Вот второй результат теста 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: я нашел phpunit билет на эту тему: билет 417