Witam
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:
  1. <ns1:getTasksDetailResponse>
  2. <Result xsi:type='SOAP-ENC:Struct'>
  3. <arrayOfObject SOAP-ENC:arrayType='SOAP-ENC:Struct[3]' xsi:type='SOAP-ENC:Array'>
  4. <item xsi:type='SOAP-ENC:Struct'>
  5. <id xsi:type='xsd:string'>
  6. 1
  7. </id>
  8. <name xsi:type='xsd:string'>
  9. Wdrozenie
  10. </name>


Cały czas tam jest xsi:type='SOAP-ENC:Struct'

Kod:

Utworzenie serwera:
  1. $server = new SoapServer("xxx.wsdl");
  2. $server->setClass('soapxxx');
  3. $soapHeader = new SoapHeader('auth', 'no logged');
  4. $server->setPersistence(SOAP_PERSISTENCE_SESSION);
  5. $server->handle();


Klasa z php.net będąca rozwiązaniem:
  1. abstract class SOAPable {
  2. public function getAsSOAP() {
  3. foreach($this as $key=>&$value) {
  4. $this->prepareSOAPrecursive($this->$key);
  5. }
  6. return $this;
  7. }
  8.  
  9. private function prepareSOAPrecursive(&$element) {
  10. if(is_array($element)) {
  11. foreach($element as $key=>&$val) {
  12. $this->prepareSOAPrecursive($val);
  13. }
  14. $element=new SoapVar($element,SOAP_ENC_ARRAY);
  15. } elseif(is_object($element)) {
  16. if($element instanceof SOAPable) {
  17. $element->getAsSOAP();
  18. }
  19. $element=new SoapVar($element,SOAP_ENC_OBJECT);
  20. }
  21. }
  22. }


Klasa przechowująca dane:
  1. class containerClass extends SOAPable{
  2. public $arrayOfObject;
  3. public function __construct($arrayOfObject) {
  4. $this->arrayOfObject = $arrayOfObject;
  5. }
  6. }


Metoda będąca częścią interfejsu serwera i zwracająca tablicę obiektów:
  1. public function getTasksDetail($userId) {
  2.  
  3. ...
  4.  
  5. $response = new containerClass($tasksResponse);
  6. $response->getAsSOAP();
  7.  
  8. return $response;
  9. }

Gdzie $taskResponse jest tablicą obiektów.

Fragment zwardampowanej zmiennej $response:
  1. object(containerClass)#137 (1) {
  2. ["arrayOfObject"]=>
  3. object(SoapVar)#147 (2) {
  4. ["enc_type"]=>
  5. int(300)
  6. ["enc_value"]=>
  7. array(9) {
  8. [0]=>
  9. object(SoapVar)#138 (2) {
  10. ["enc_type"]=>
  11. int(301)
  12. ["enc_value"]=>
  13. object(responseSoap)#128 (14) {
  14. ["id"]=>
  15. string(1) "1"
  16. ["name"]=>
  17. string(10) "WdroĹĽenie"
  18. ["working_hours"]=>
  19. string(16) "1.00000000000000"
  20. ["invested_hours"]=>
  21. string(17) "22.50000000000000"
  22. ["status"]=>


Natomiast w pliku WSDL dane zwracane przez funkcję opisaną getTasksDetail jest zdefiniowanwa w następujący sposób:
  1. <message name='getTasksDetailResponse'>
  2. <part name='Result' type='soapenc:Object'/>
  3. </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. wstydnis.gif