检查 URL 是否有效(来自 php Soap 客户端)

发布于 2024-08-04 13:58:24 字数 541 浏览 3 评论 0原文

我正在编写一个 Web 应用程序,它允许用户为 SoapClient 指定 URL。我想验证当用户提交表单时 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 来完成此操作。

这应该是一个致命错误吗?

编辑

在阅读rogeriopvl的答案后,我重新意识到我应该说我已经尝试了soapclient构造函数的“例外”选项和(绝望中)use-soap-error-handler函数。

I am writing a web app which will allow the user to specify a URL for a SoapClient. I wanted to validate that php can connect to the client when the user submits a form. I thouhgt I could do this via try catch or set_error_handler (or some combination of the two). However it looks like this is not possible for fatal errors. Is there a way to get SoapClent to test a URL which won't throw an unrecoverable error?

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

I want it to flag an error as the URL doesn’t exist, but I would like to be able to catch it.

Otherwise I suppose I could try to download and validate the URL myself, but I would have thought that it would be possible to do it from the SoapClient.

Should this be a fatal error?

Edit

After reading rogeriopvl's answer I reaslise that I should have said that I had tried the 'exceptions' option to the soapclient constructor and (in desperation) the use-soap-error-handler function.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

皓月长歌 2024-08-11 13:58:24

你用的是xdebug吗?根据 此 PHP 错误报告和讨论,该问题至少已得到修复PHP 5.1,但是这个 xdebug bug 与“异常转换的致命错误”混淆一种不生成异常并且致命错误“泄漏”的方法。

我可以在启用 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);
}

这会按预期触发异常,并且我在 catch 子句中得到了一个正确的 SoapFault 对象,并带有以下消息:

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

所以基本上异常按照广告中的方式工作。如果它们在您的情况下不起作用,您可能会遇到 xdebug 错误,或者可能会遇到其他第 3 方组件的类似问题。

Are you using xdebug? According to this PHP bug report and discussion, the issue has been fixed at least since PHP 5.1, but this xdebug bug messes with 'fatal error to exception conversions' in a way that the exception is not generated and the fatal error 'leaks through'.

I can reproduce this locally, with xdebug enabled:

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

This gives me the fatal error you described, without even entering the catch clause:

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

It works if I disable xdebug right before the call:

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

This triggers the exception as expected, and I get a proper SoapFault Object in the catch clause with a message of:

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

So basically exceptions work as advertised. If they don't work in your case, you might encounter the xdebug bug, or maybe a similar issue with another 3rd party component.

只等公子 2024-08-11 13:58:24

引用 SoapClient 文档

异常选项是一个布尔值,定义soap错误是否抛出SoapFault类型的异常。

所以你应该尝试类似的方法:

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

这种方式会抛出 SoapFault 异常,允许你去抓住他们。

Quoting SoapClient documentation:

The exceptions option is a boolean value defining whether soap errors throw exceptions of type SoapFault.

So you should try something like:

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

This way will throw SoapFault exceptions allowing you to catch them.

挥剑断情 2024-08-11 13:58:24

请参阅: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();
     }
   }

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

Possible solution:

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();
     }
   }
风吹短裙飘 2024-08-11 13:58:24

您可以尝试执行curl 或fsockopen 请求来检查URL 是否有效。

you could try and do a curl or fsockopen request to check the URL is valid.

难得心□动 2024-08-11 13:58:24

供您参考,我正在使用 SoapClient 和 PHPUnit 来测试远程 WebServices 并遇到了同样的问题!

  • 当使用旧的 PHPUnit 版本(3.3.x)作为第三方时,phpunit 崩溃
  • 当使用当前版本的 PHPUnit(3.4.6)作为第三方时,phpunit 显示“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

注意:我找到了关于此主题的 phpunit 票证:票 417

For your information, i'm using SoapClient with PHPUnit to test remote WebServices and got the same problem!

  • when using an old PHPUnit version (3.3.x) as third party, phpunit crash
  • when using current version of PHPUnit (3.4.6) as third party, phpunit display "RuntimeException".

Here is my first test method :

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

Here is PHPUnit first result :

There was 1 error:

1) MyTestCase::testUnavailableURL
RuntimeException: 


FAILURES!

Here is my second test method :

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

Here is PHPUnit second test result :

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: i found a phpunit ticket on this subject : ticket 417

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文