Vor ein paar Tagen stand ich vor dem Problem, dass ich an einen Service mehrere XML-Nodes mit dem gleichen Element-Namen übergeben musste. Im XML ja auch kein Problem, nur leider etwas blöd, wenn man ein Array an den Soap-Client übergibt. In diesem Fall steht man etwas doof dar, weil man Array-Keys ja schlecht doppelt und dreifach vergeben kann.
Also dachte ich mir: Einfach den XML-Request des Clients modifizieren. Das ist aber leichter gesagt als getan. Ich habe zumindest keine Funktion gefunden, welche man überschreiben könnte um sich in den Serialisierungsprozess zu hängen. Also musste ich am Ende
- doRequest überschreiben,
- das Ganze Zeug wieder in ein Objekt wandeln,
- mit xPath die XML-Node rausziehen,
- die neuen Elemente einfügen
- und alles wieder zusammenpacken.
Puh. Das hatte ich mir etwas einfacher vorgestellt… Außerdem ist das Ganze nur bei recht überschaubaren Requests zu Empfehlen. Ansonsten einfach von Arrays abweichen und Objekte übergeben. Dann ist man auf der sicheren Seite. Hier der Code dazu:
class OwnClient extends SoapClient { protected $_additionalData = array(); public function addAdditionalData($key, $value) { $this->_additionalData[$key] = $value; } public function __doRequest($request, $location, $action, $version, $one_way = 0) { if (count($this->_additionalData) > 0) { try { $dom = new DOMDocument('1.0'); // Loads the SOAP request to the Document $dom->loadXML($request); // Create a XPath object to query the request $path = new DOMXPath($dom); //search for a node $clientDataXPath = $path->query('//SOAP-ENV:Envelope/SOAP-ENV:Body/myElement'); if ($clientDataXPath->length == 1) { $clientData = $clientDataXPath->item(0); // Append additional Data foreach ($this->_additionalData as $key => $value) { $newElement = $dom->createElement('additionalData'); $newElement->appendChild($dom->createElement('name', $key)); $newElement->appendChild($dom->createElement('value', $value)); $clientData->appendChild($newElement); } } // Save the modified SOAP request $request = $dom->saveXML(); } catch (DOMException $e) { // Exception handling } } //doRequest return parent::__doRequest($request, $location, $action, $version, $one_way); } }
Fertig.