Using Guzzle to consume SOAP

后端 未结 4 1958
夕颜
夕颜 2021-02-12 04:24

I\'m loving the Guzzle framework that I just discovered. I\'m using it to aggregate data across multiple API\'s using different response structures. It\'s worked find with JSON

相关标签:
4条回答
  • 2021-02-12 05:09

    You can get Guzzle to send SOAP requests. Note that SOAP always has an Envelope, Header and 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>
    

    The first thing I do is build the xml body with SimpleXML:

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

    We then wrap our xml body with the soap envelope, header and body.

    $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
    

    We then need to find out what our endpoint is in the api docs.

    We then build the client in 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 !!!';
    }
    
    0 讨论(0)
  • 2021-02-12 05:22

    Old Topic, but as I was searching for the same answer, it seems async-soap-guzzle is doing the job.

    0 讨论(0)
  • 2021-02-12 05:27

    Guzzle HTTP can be used for SOAP requests & works like a charm:

    Below is the way I have implemented.

    Create variables:

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

    Create a function to form a soap request.

    public function generateSoapRequest($soapBody){
        return $this->openSoapEnvelope . $this->soapHeader . $soapBody . $this->closeSoapEnvelope;
    }
    

    Define a body & call generateSoapRequest method. e.g:

    $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());
    
    0 讨论(0)
  • 2021-02-12 05:29

    IMHO Guzzle doesn't have full SOAP support and works only with HTTP requests. src/Guzzle/Http/ClientInterface.php Line:76

    public function createRequest(                                              
        $method = RequestInterface::GET,                                        
        $uri = null,                                                            
        $headers = null,                                                        
        $body = null,                                                           
        array $options = array()                                                
    ); 
    

    Even if SOAP server is configured to negotiate on port 80 I think php SoapClient is more appropriate solution here as it supports WSDL

    0 讨论(0)
提交回复
热议问题