php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #31869 Returned SOAP-structs are mapped to stdclass instead of matching user class.
Submitted: 2005-02-07 10:17 UTC Modified: 2005-03-05 14:05 UTC
Votes:2
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: wolfgang dot glas at ev-i dot at Assigned: dmitry (profile)
Status: Not a bug Package: SOAP related
PHP Version: 5.0.3 OS: any
Private report: No CVE-ID: None
 [2005-02-07 10:17 UTC] wolfgang dot glas at ev-i dot at
Description:
------------
The code fragment below shows a PHP SOAP client calling the 
echoStruct() function from the 'base' example of AXIS C++ 
(Apcahe's C++ SOAP-server). This example is supposedly 
included in most SOAP servers. If not, contact me for more 
information. 
 
The struct SOAPStruct is defined in the according wsdl-file 
an the struct correctly passed over to the SOAP server. 
 
When an object of type SOAPStruct is returned by the 
SOAPClient, the returned object is of type 'stdclass' with 
the appropriate attributes. 
 
The returned object can be easily mappedd back to the 
user-defined class, as shown below in the fromStdClass() 
member function. 
 
Nevertheless, it would feasible for most users, if the 
SOAPClient mapped the returned value directly to an Object 
of type 'class SOAPStruct' in the case that the user 
defined a class with a name that matches the struct name in 
the wsdl-file. 
 
IMHO, this feature should become part of the PHP-5.1 
development schedule. 
 
  TIA for considering this suggestion, 
 
    Wolfgang 

Reproduce code:
---------------
class SOAPStruct
{
   public $varString;
   public $varInt;
   public $varFloat;
   function __construct($s= "",$i = 0,$f = 0.0) {
        $this->varString=$s;
        $this->varInt=$i;
        $this->varFloat=$f;
   }
   function fromStdClass($v) {
     foreach($v as $key => $value) {
       $this->$key= $value;
     }
   }
   function printMe() {
        echo "string=".$this->varString."\nint=".$this->varInt."\nfloat=".$this->varFloat."\n";
    }
}
$s=new SOAPStruct("s_string",43,3.1415926535);
$r=new SOAPStruct;
$client = new SoapClient("http://localhost:8080/axis/base?wsdl");
echo "********* echoStruct:\n";
echo "**** s:\n"; $s->printMe();
$r->fromStdClass($client->echoStruct($s));
echo "**** r:\n"; $r->printMe();



Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-02-10 12:52 UTC] dmitry@php.net
You can do this with "classmap" option in SoapClient/SoapServer constructor.

$client = new SoapClient(("http://localhost:8080/axis/base?wsdl",
  array("classmap"=>array("SOAPStruct"=>"SOAPStruct")));
 [2005-02-10 16:02 UTC] wolfgang dot glas at ev-i dot at
Thanks Dimitri for this pointer. It actually seem to work  
for the example I posted.  
  
Nevertheless, when using an array of wsdl-structs, the  
classmap specifiaction seems to be ignored: 
 
To be precise, when I extend my example with the following 
code: 
----------------------- 
echo "********* echoStruct:\n"; 
echo "**** s:\n"; $s->printMe(); 
$r = $client->echoStruct($s); 
echo "**** r:\n"; $r->printMe(); 
$sa = array(new SOAPStruct("s_string0",43,3.1415926535), 
            new SOAPStruct("s_string1",44,17.47), 
            new SOAPStruct("s_string2",45,27.30)); 
 
$ra = $client->echoStructArray($sa); 
 
echo "**** sa:\n"; 
     foreach($sa as $key => $value) { 
       echo "$key => "; $value->printMe();  
     } 
echo "**** ra:\n"; 
     foreach($ra as $key => $value) { 
       echo "$key => "; $value->printMe(); <--- 
     } 
----------------- 
, I get the following error: 
Fatal error: Call to undefined method stdClass::printMe() 
in /home/wglas/axis/php/base.php on line 68 
The line number refers to the line marked with <--- above. 
The code for returning a single structure (echoStruct call 
above) is running without any problem. 
 
So it seems to me, that members of an array of wsdl-structs 
are mapped to stdclass, regardless of the classmap 
directive in the SOAPClient ctor. 
 
   Wolfgang
 [2005-03-05 14:05 UTC] dmitry@php.net
I just tested this with PHP-5.0.3 and latest CVS versions. Works fine for me.

<?php
class SoapStruct {
  public    $varString;
  protected $varInt;
  private   $varFloat;

  function SoapStruct($a, $b, $c) {
    $this->varString = $a;
    $this->varInt = $b;
    $this->varFloat = $c;
  }

  function printMe() {
    var_dump($this);
  }
}

function echoStructArray($a) {
  return $a;
}

class LocalSoapClient extends SoapClient {
  function __construct($wsdl, $options) {
    parent::__construct($wsdl, $options);
    $this->server = new SoapServer($wsdl, $options);
    $this->server->addFunction('echoStructArray');
  }

  function __doRequest($request, $location, $action, $version) {
    ob_start();
    $this->server->handle($request);
    $response = ob_get_contents();
    ob_end_clean();
    return $response;
  }

}

$x = new LocalSoapClient("round2_base.wsdl", 
                         array("classmap"=>array("SOAPStruct"=>"SOAPStruct")));
$y = $x->echoStructArray(array(new SoapStruct("0", 3, 4.1),
                               new SoapStruct("1", 5, 6.2)));
foreach($y as $z) {
  $z->printMe();
}
?>

 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Mar 29 09:01:28 2024 UTC