In a SOAP service I work on, I needed to generate a response that repeated the same element.
Something like this.
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.example.com/WebService/"> <SOAP-ENV:Body> <ns1:getPhoneNumbersResponse> <numbers> <number>123341344</number> <number>329822938</number> </numbers> </ns1:getPhoneNumbersResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
Getting this to work in the PHP code took a bit of fussing around. You can’t just create a hash, because the hash can’t include more than one key called ‘number.’
$this->response = new GetPhoneNumbersResponse(); $numbers = array(); $number1 = new \SoapVar('123341344', XSD_STRING, NULL, NULL, 'number'); $numbers = $number1; $number2 = new \SoapVar('329822938', XSD_STRING, NULL, NULL, 'number'); $numbers = $number2; $this->response->numbers = new \SoapVar($numbers, SOAP_ENC_OBJECT, NULL, NULL, 'numbers');
In my wsdl, it looks something like this.
<xsd:element name="getPhoneNumbersResponse"> <xsd:complexType> <xsd:sequence> <xsd:element name="numbers" maxOccurs="1" minOccurs="1" type="tns:getPhoneNumbersResultInformation"></xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:complexType name="getPhoneNumbersResultInformation"> <xsd:sequence> <xsd:element name="number" maxOccurs="unbounded" type="xsd:string" /> </xsd:sequence> </xsd:complexType>
The key is that in the PHP code, I had to use the SoapVar object and force the data to be in the correct tag.
$number1 = new \SoapVar('123341344', XSD_STRING, NULL, NULL, 'number');
That makes a “number” element.
I then assign it to an array $numbers; Once that array has all of the ‘number’ SOAP strings, I then add it to my response object and put it in the numbers tag.
$this->response->numbers = new \SoapVar($numbers, SOAP_ENC_OBJECT, NULL, NULL, 'numbers');
Also note that “number” is a string (XSD_STRING) and “numbers” is cast as a SOAP object (SOAP_ENC_OBJECT).
I’ve actually had to solve this a few times, and each time I forget how to do it, so hopefully I’ll remember that I wrote this down.
You may see reference on Stackoverflow for using the wsdl array stuff, I played around with that, but this approach documented here is more straightforward.