首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在PHP中处理Soap超时

在PHP中处理Soap超时
EN

Stack Overflow用户
提问于 2009-05-07 14:59:40
回答 8查看 78.4K关注 0票数 36

我正在进行一个项目,在该项目中,我使用SOAP服务验证来自用户的信息。我目前正在处理错误,假设我收到了来自web服务的响应,但也需要处理服务超时或不可用的边缘情况。

在超时或服务不可用的情况下,我需要假装请求是成功的( web服务批准了信息),但我不清楚抛出了哪些异常。

一些伪码:

代码语言:javascript
运行
复制
// $client is PHP's SoapClient class
try {
  $response = $client->SomeSoapRequest();
}
catch(SoapFault $e){
  // handle issues returned by the web service
}
catch(Exception $e){
  // handle PHP issues with the request
}

但我似乎找不到:

  1. 超时是SoapFault吗?如果是,那么区分超时错误和web服务问题(比如类型错误等)的最佳方法是什么?我发现有一个页面提到了一个错误,其中的消息是“错误加载标题”的结果,但是没有提到这是否是Soap错误。
  2. 如何可能出现服务不可用的情况?PHP异常似乎是有意义的( SoapFault将从不可用的套接字问题或类似的web服务中返回)?
  3. 是否有我可以测试超时的现有服务(例如示例)?大多数与超时相关的讨论似乎都与通过扩展默认超时设置来防止超时有关,在这种情况下,这种设置并不理想。
EN

回答 8

Stack Overflow用户

发布于 2013-01-11 22:18:10

1)在超时的情况下,PHP抛出带有faultcode="HTTP"faultstring="Error Fetching http headers"faultcode="HTTP"异常。

2)在我看来,区分超时错误和web服务问题的最佳方法是查看faultcodeSoapFault类faultstring成员。

特别是,faultcode元素用于软件来提供识别故障的算法机制。

因为您也可以在PHP手册注释中读取,所以没有读取faultcode属性的方法,所以您必须直接访问它(例如。$e->faultcode),因为getCode()方法不工作。

SOAP1.1规格faultcode字段定义了四个可能的值:

  • VersionMismatch:处理方为SOAP信封元素找到了一个无效的命名空间
  • MustUnderstand::SOAP标头元素的直接子元素,处理方不理解或不遵守该元素,其中包含一个值为"1“的SOAP mustUnderstand属性。
  • Client :错误的客户端类表示消息格式不正确,或者没有包含适当的信息才能成功。例如,消息可能缺少适当的身份验证或支付信息。这通常表明,如果不改变,就不应对该信息表示不满。
  • 服务器:服务器类错误指示消息不能被处理,原因不是直接归因于消息本身的内容,而是消息的处理。例如,处理可能包括与上游处理器通信,而上游处理器没有响应。消息可能会在稍后的某个时间点成功。

除了这些代码之外,PHP还使用HTTP代码来识别在协议级别上发生的错误(例如:套接字错误);例如,如果在http.c源代码中搜索add_soap_fault,则可以在生成某些此类错误时看到这些错误。

通过在PHP扩展源文件中搜索add_soap_faultsoap_server_fault函数,我构建了以下PHP SoapFault异常列表:

代码语言:javascript
运行
复制
HTTP
----
Unable to parse URL
Unknown protocol. Only http and https are allowed.
SSL support is not available in this build
Could not connect to host
Failed Sending HTTP SOAP request
Failed to create stream??
Error Fetching http headers
Error Fetching http body: No Content-Length: connection closed or chunked data
Redirection limit reached: aborting
Didn't recieve an xml document
Unknown Content-Encoding
Can't uncompress compressed response
Error build soap request


VersionMismatch
---------------
Wrong Version


Client
------
A SOAP 1.2 envelope can contain only Header and Body
A SOAP Body element cannot have non Namespace qualified attributes
A SOAP Envelope element cannot have non Namespace qualified attributes
A SOAP Header element cannot have non Namespace qualified attributes
Bad Request
Body must be present in a SOAP envelope
Can't find response data
DTD are not supported by SOAP
encodingStyle cannot be specified on the Body
encodingStyle cannot be specified on the Envelope
encodingStyle cannot be specified on the Header
Error cannot find parameter
Error could not find "location" property
Error finding "uri" property
looks like we got "Body" with several functions call
looks like we got "Body" without function call
looks like we got no XML document
looks like we got XML without "Envelope" element
Missing parameter
mustUnderstand value is not boolean
SoapClient::__doRequest() failed
SoapClient::__doRequest() returned non string value
Unknown Data Encoding Style
Unknown Error
DataEncodingUnknown


MustUnderstand
--------------
Header not understood


Server
------
Couldn't find WSDL
DTD are not supported by SOAP
Unknown SOAP version
WSDL generation is not supported yet

3)要模拟超时条件,请尝试使用以下代码:

soapclient.php

代码语言:javascript
运行
复制
<?php

ini_set('default_socket_timeout', 10);

$client = new SoapClient(null, 
  array(
    'location' => "http://localhost/soapserver.php",
    'uri'      => "http://localhost/soapserver.php",
    'trace'    => 1
  )
);

try {
    echo $return = $client->__soapCall("add",array(41, 51));
} catch (SoapFault $e) {
    echo "<pre>SoapFault: ".print_r($e, true)."</pre>\n";
    //echo "<pre>faultcode: '".$e->faultcode."'</pre>";
    //echo "<pre>faultstring: '".$e->getMessage()."'</pre>";
}

?>

soapserver.php

代码语言:javascript
运行
复制
<?php

function add($a, $b) {
  return $a + $b;
}

sleep(20);

$soap = new SoapServer(null, array('uri' => 'http://localhost/soapserver.php'));
$soap->addFunction("add");
$soap->handle();

?>

注意,sleep调用在SoapServer.php脚本中的时间(20)比为SoapClient.php脚本中的default_socket_timeout参数指定的时间(10)长。

如果您想要模拟服务不可用性,例如,您可以在location脚本中将http协议更改为https,假设您的web服务器不是为SSL配置的;这样做,PHP应该抛出一个“无法连接到主机”SoapFault。

票数 36
EN

Stack Overflow用户

发布于 2010-09-08 19:41:01

在HTTPS上进行SOAP调用时,似乎没有考虑到default_socket_timeout

错误在编写时打开。正如在删除的答案http://www.darqbyte.com/2009/10/21/timing-out-php-soap-calls/中引用的博客文章Robert的评论所指出的那样,本文讨论的解决方法(用curl请求覆盖SoapClient::__doRequest() )也可以解决这个问题。

另一个相关的错误是:

在博客文章中提到的代码经历了一些更改,可以在支持HTTP身份验证的最新形式中找到:

无论如何,不应该再需要解决方法了,因为这个问题已经在PHP扩展中解决了。

票数 7
EN

Stack Overflow用户

发布于 2009-05-07 16:53:39

处理服务中的超时

代码语言:javascript
运行
复制
$client = new SoapClient($wsdl, array("connection_timeout"=>10));

// SET SOCKET TIMEOUT
if(defined('RESPONSE_TIMEOUT') &&  RESPONSE_TIMEOUT != '') {
 ini_set('default_socket_timeout', RESPONSE_TIMEOUT);
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/835184

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档