我喜欢我刚刚发现的 Guzzle 框架。我正在使用它使用不同的响应结构跨多个 API 聚合数据。它适用于 JSON 和 XML,但我需要使用的服务之一使用 SOAP。是否有使用 Guzzle 使用 SOAP 服务的内置方法?
问问题
28502 次
4 回答
17
您可以让 Guzzle 发送 SOAP 请求。请注意,SOAP 总是有一个 Envelope、Header 和 Body。
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<NormalXmlGoesHere>
<Data>Test</Data>
</NormalXmlGoesHere>
</soapenv:Body>
我做的第一件事是使用 SimpleXML 构建 xml 主体:
$xml = new SimpleXMLElement('<NormalXmlGoesHere xmlns="https://api.xyz.com/DataService/"></NormalXmlGoesHere>');
$xml->addChild('Data', 'Test');
// Removing xml declaration node
$customXML = new SimpleXMLElement($xml->asXML());
$dom = dom_import_simplexml($customXML);
$cleanXml = $dom->ownerDocument->saveXML($dom->ownerDocument->documentElement);
然后我们用肥皂信封、标题和正文包装我们的 xml 正文。
$soapHeader = '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body>';
$soapFooter = '</soapenv:Body></soapenv:Envelope>';
$xmlRequest = $soapheader . $cleanXml . $soapFooter; // Full SOAP Request
然后我们需要在 api 文档中找出我们的端点是什么。
然后我们在 Guzzle 中构建客户端:
$client = new Client([
'base_url' => 'https://api.xyz.com',
]);
try {
$response = $client->post(
'/DataServiceEndpoint.svc',
[
'body' => $xmlRequest,
'headers' => [
'Content-Type' => 'text/xml',
'SOAPAction' => 'https://api.xyz.com/DataService/PostData' // SOAP Method to post to
]
]
);
var_dump($response);
} catch (\Exception $e) {
echo 'Exception:' . $e->getMessage();
}
if ($response->getStatusCode() === 200) {
// Success!
$xmlResponse = simplexml_load_string($response->getBody()); // Convert response into object for easier parsing
} else {
echo 'Response Failure !!!';
}
于 2017-07-14T02:40:14.870 回答
5
恕我直言,Guzzle 没有完整的 SOAP 支持,仅适用于 HTTP 请求。src/Guzzle/Http/ClientInterface.php 行:76
public function createRequest(
$method = RequestInterface::GET,
$uri = null,
$headers = null,
$body = null,
array $options = array()
);
即使 SOAP 服务器配置为在端口 80 上进行协商,我认为 php SoapClient 在这里是更合适的解决方案,因为它支持 WSDL
于 2014-02-13T06:59:40.247 回答
4
老话题,但是当我在寻找相同的答案时,似乎async-soap-guzzle正在完成这项工作。
于 2016-08-31T08:24:31.303 回答
3
Guzzle HTTP 可用于 SOAP 请求,其工作原理就像一个魅力:
以下是我实施的方式。
创建变量:
public function __construct(Request $request) {
$this->request = $request;
$this->openSoapEnvelope = '<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:tem="http://tempuri.org/">';
$this->soapHeader = '<soap:Header>
<tem:Authenticate>
<-- any header data goes here-->
</tem:Authenticate>
</soap:Header>';
$this->closeSoapEnvelope = '</soap:Envelope>';
}
创建一个函数来形成一个肥皂请求。
public function generateSoapRequest($soapBody){
return $this->openSoapEnvelope . $this->soapHeader . $soapBody . $this->closeSoapEnvelope;
}
定义一个主体并调用 generateSoapRequest 方法。例如:
$soapBody = '<soap:Body>
<tem:GetSomeDetails/>
</soap:Body>';
$xmlRequest = $this->generateSoapRequest($soapBody);
$client = new Client();
$options = [
'body' => $xmlRequest,
'headers' => [
"Content-Type" => "text/xml",
"accept" => "*/*",
"accept-encoding" => "gzip, deflate"
]
];
$res = $client->request(
'POST',
'http://your-soap-endpoint-url',
$options
);
print_r($res->getBody());
于 2018-11-15T13:21:22.777 回答