Использование Guzzle для использования SOAP

Мне нравится только что обнаруженный мной фреймворк Guzzle. Я использую его для агрегирования данных по нескольким API с использованием разных структур ответа. Он работал с JSON и XML, но одна из служб, которые мне нужно использовать, использует SOAP. Есть ли встроенный способ использования сервисов SOAP с помощью Guzzle?


person LordZardeck    schedule 03.10.2013    source источник
comment
Я также хотел бы получить больше информации по этой теме. В документации Guzzle ничего не упоминается о файлах .wsdl или SOAP.   -  person Rvanlaak    schedule 07.10.2013


Ответы (4)


Вы можете заставить Guzzle отправлять запросы SOAP. Обратите внимание, что SOAP всегда имеет конверт, заголовок и тело.

<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>

Первое, что я делаю, это создаю тело xml с помощью 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);

Затем мы оборачиваем наше тело 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 !!!';
}
person alakin_11    schedule 14.07.2017

IMHO 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.

person ishenkoyv    schedule 13.02.2014
comment
Я думаю, что guzzle теперь в версии 6. Вы знаете, внесли ли они какие-либо изменения для поддержки SOAP? - person gmponos; 03.09.2015

Старая тема, но поскольку я искал тот же ответ, кажется, async-soap-guzzle делает свою работу.

person Raphael1px    schedule 31.08.2016
comment
эта библиотека выполняет дополнительный вызов API для запроса eahc с использованием стандартной библиотеки php soap. Любая идея, почему, можем ли мы избавиться от этого дополнительного вызова api? - person Bogdan Dubyk; 02.06.2020

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());
person user3785966    schedule 15.11.2018