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
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 !!!';
}
Old Topic, but as I was searching for the same answer, it seems async-soap-guzzle is doing the job.
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());
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