理解多部分消息的PHP SOAP客户端?
2022-08-30 23:25:41
有这样的野兽吗?随 PHP 附带的简单 SOAP 客户端不理解多部分消息。提前致谢。
原生 PHP SoapClient
类不支持多部分消息(并且在所有 WS-* 事务中都受到严格限制),我也认为 PHP 编写的库 NuSOAP 和Zend_Soap都无法处理此类 SOAP 消息。
我可以想到两种解决方案:
扩展类并覆盖该方法以获取实际的响应字符串,然后您可以随心所欲地解析该字符串。SoapClient
SoapClient::__doRequest()
class MySoapClient extends SoapClient
{
public function __doRequest($request, $location, $action, $version, $one_way = 0)
{
$response = parent::__doRequest($request, $location, $action, $version, $one_way);
// parse $response, extract the multipart messages and so on
}
}
这可能有点棘手 - 但值得一试。
使用更复杂的 SOAP 客户端库进行 PHP。我脑海中浮现的第一个也是唯一一个是WSO2 WSF/PHP,它具有SOAP MTOM,WS-Addressing,WS-Security Security,WS-SecurityPolicy,WS-Secure Conversation和WS-ReliableMessaging,代价是必须安装本机PHP扩展。
尽管这里已经给出了很多答案,但我已经整理了一个通用的解决方案,请记住,XML可以在没有包装器的情况下出现。
class SoapClientExtended extends SoapClient
{
/**
* Sends SOAP request using a predefined XML
*
* Overwrites the default method SoapClient::__doRequest() to make it work
* with multipart responses.
*
* @param string $request The XML content to send
* @param string $location The URL to request.
* @param string $action The SOAP action. [optional] default=''
* @param int $version The SOAP version. [optional] default=1
* @param int $one_way [optional] ( If one_way is set to 1, this method
* returns nothing. Use this where a response is
* not expected. )
*
* @return string The XML SOAP response.
*/
public function __doRequest(
$request, $location, $action, $version, $one_way = 0
) {
$result = parent::__doRequest($request, $location, $action, $version, $one_way);
$headers = $this->__getLastResponseHeaders();
// Do we have a multipart request?
if (preg_match('#^Content-Type:.*multipart\/.*#mi', $headers) !== 0) {
// Make all line breaks even.
$result = str_replace("\r\n", "\n", $result);
// Split between headers and content.
list(, $content) = preg_split("#\n\n#", $result);
// Split again for multipart boundary.
list($result, ) = preg_split("#\n--#", $content);
}
return $result;
}
}
这仅在使用选项 初始化 时有效。SoapClientExtended
trace => true