The classmap option can be used to map some WSDL types to PHP classes. This option must be an array with WSDL types as keys and names of PHP classes as values.
我创建我的客户端:
$api = new SOAPClient('http://example.com/soap.wsdl',[ 'location' => 'http://example.com/soap/endpoint','soap_version' => SOAP_1_2,'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP,'cache_wsdl' => WSDL_CACHE_BOTH,'classmap' => [ 'APIResultObject' => 'Result' ],# TODO: Set for debug only? 'trace' => TRUE,'exceptions' => TRUE ]);
这样工作,当我调用$api-> method(‘param’)时,我会返回一个Result对象(而不是一个StdClass对象).问题是Result :: __ construct()方法永远不会被调用,所以Result的一些私有属性从不被设置.
以下是结果是:
class DataClass{ protected $data; function __construct(){ $this->data = ['a' => 0,'b' => 1,'c' => 2]; } } class Result extends DataClass{ public $value,$name,$quantity; function __construct(array $values){ parent::__construct(); foreach(['value','name','quantity'] as $var){ $this->$var = isset($values[$var]) ? $values[$var] : NULL; } } function getData(){ return $this->data[$this->name]; } }
发生了什么,我正在做$api->方法(‘param’) – > getData()并获得以下错误:
Notice: Undefined property: Result::$data
在获取SOAP响应时,如何调用构造函数?我试过使用__wakeup()
,但似乎也没有.
附:我用一个小的解决方案“解决了”它,但我不认为它是理想的.这是我做的:
function getData(){ if($this->data === NULL){ parent::__construct(); } return $this->data[$this->name]; }
因为在bug报告中提供了一些建议(在web dot de上的miceleparkip):
This is not a bug. It’s quite normal.
The soap object is created on the server side. So the constructor is just called on the server.
我分享她的立场
同一个错误报告中的后续评论(hotblocks dot nl的PHP)不同意:
The server doesn’t create objects,it sends XML. The client decodes that XML and creates the objects.
虽然从技术角度来看这是无可争议的,但“抽象”对象可以在服务器端创建.无论是首先转换为XML,然后在客户端重建,都是低级别的关注,应用层不需要注意.
如果您的应用程序需要具有比服务器提供的功能更多的功能的对象,我将创建一个本地类,该对象将SOAPClient创建的对象作为构造函数参数:
class MySoapResultClass { // whatever } class LocalApplicationClass { public function __construct(MySoapResultClass $soapResult) { // your local initialization code $this->data = ['a' => 0,'c' => 2]; // then either extract your data from $soapResult,// or just store a reference to it } public function getData(){ return $this->data[$this->name]; } } $api = new SOAPClient(...); $soapResult = $api->method('param'); $myUsefulObject = new LocalApplicationClass($soapResult);