【问题标题】:Using Guzzle to consume SOAP使用 Guzzle 使用 SOAP
【发布时间】:2013-10-10 20:08:42
【问题描述】:

我喜欢我刚刚发现的 Guzzle 框架。我正在使用它使用不同的响应结构跨多个 API 聚合数据。它适用于 JSON 和 XML,但我需要使用的服务之一使用 SOAP。是否有使用 Guzzle 使用 SOAP 服务的内置方式?

【问题讨论】:

  • 我还想获得有关此主题的更多信息。 Guzzle 文档没有提及任何有关 .wsdl 文件或 SOAP 的内容。

标签: soap guzzle


【解决方案1】:

恕我直言,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

【讨论】:

  • 我认为 guzzle 现在是第 6 版。您知道他们是否为支持 SOAP 做了任何更改?
【解决方案2】:

老话题,但当我在寻找相同的答案时,似乎async-soap-guzzle 正在完成这项工作。

【讨论】:

  • 这个库使用标准 php soap 库对 eahc 请求进行额外的 API 调用,知道为什么,我们可以摆脱额外的 api 调用吗?
【解决方案3】:

您可以让 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 !!!';
}

【讨论】:

    【解决方案4】:

    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>';
    }
    

    创建一个函数来形成一个soap请求。

    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());
    

    【讨论】:

      猜你喜欢
      • 2020-09-23
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 2017-11-19
      • 2015-08-25
      • 1970-01-01
      • 1970-01-01
      • 2018-03-24
      相关资源
      最近更新 更多