Проверка 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