Mam problem z bugiem php soap który jest opisany tutaj: http://bugs.php.net/bug.php?id=31832
Znalazłem też rozwiązanie tego problemu: http://www.php.net/manual/en/ref.soap.php#83410
Jest to rozwiązanie na przykładzie przesyłania złożonej struktury z klienta do serwera, natomiast ja próbuję przesłać tablicę obiektów z serwera do klienta (poprzez zwrócenie tej tablicy jako wynik działania metody). Jednak u mnie to nie działa.
Fragment kodu odebranego przez klienta:
<ns1:getTasksDetailResponse> <Result xsi:type='SOAP-ENC:Struct'> <arrayOfObject SOAP-ENC:arrayType='SOAP-ENC:Struct[3]' xsi:type='SOAP-ENC:Array'> <item xsi:type='SOAP-ENC:Struct'> <id xsi:type='xsd:string'> 1 </id> <name xsi:type='xsd:string'> Wdrozenie </name>
Cały czas tam jest xsi:type='SOAP-ENC:Struct'
Kod:
Utworzenie serwera:
$server = new SoapServer("xxx.wsdl"); $server->setClass('soapxxx'); $soapHeader = new SoapHeader('auth', 'no logged'); $server->setPersistence(SOAP_PERSISTENCE_SESSION); $server->handle();
Klasa z php.net będąca rozwiązaniem:
abstract class SOAPable { public function getAsSOAP() { foreach($this as $key=>&$value) { $this->prepareSOAPrecursive($this->$key); } return $this; } private function prepareSOAPrecursive(&$element) { foreach($element as $key=>&$val) { $this->prepareSOAPrecursive($val); } $element=new SoapVar($element,SOAP_ENC_ARRAY); if($element instanceof SOAPable) { $element->getAsSOAP(); } $element=new SoapVar($element,SOAP_ENC_OBJECT); } } }
Klasa przechowująca dane:
class containerClass extends SOAPable{ public $arrayOfObject; public function __construct($arrayOfObject) { $this->arrayOfObject = $arrayOfObject; } }
Metoda będąca częścią interfejsu serwera i zwracająca tablicę obiektów:
public function getTasksDetail($userId) { ... $response = new containerClass($tasksResponse); $response->getAsSOAP(); return $response; }
Gdzie $taskResponse jest tablicą obiektów.
Fragment zwardampowanej zmiennej $response:
object(containerClass)#137 (1) { ["arrayOfObject"]=> object(SoapVar)#147 (2) { ["enc_type"]=> int(300) ["enc_value"]=> [0]=> object(SoapVar)#138 (2) { ["enc_type"]=> int(301) ["enc_value"]=> object(responseSoap)#128 (14) { ["id"]=> string(1) "1" ["name"]=> string(10) "WdroĹĽenie" ["working_hours"]=> string(16) "1.00000000000000" ["invested_hours"]=> string(17) "22.50000000000000" ["status"]=>
Natomiast w pliku WSDL dane zwracane przez funkcję opisaną getTasksDetail jest zdefiniowanwa w następujący sposób:
<message name='getTasksDetailResponse'> <part name='Result' type='soapenc:Object'/> </message>
Najwięcej wątpliwości mam do type w par name. Ale być może macie inne pomysły co nie tak robię? Pierwszy raz mam styczność z SOAP więc być może robię jakiś głupi błąd.
