问题(在 PHP5 下使用 SOAP 扩展)传输包含对象或对象数组的对象。嵌套对象无法传输。
解决方案
此类由我通过反复试验开发。因此,对于大多数在 PHP5 下编写代码的开发人员来说,这 23 行代码解决了使用 SOAP 扩展的命运。
<?php
/*
根据 PHP5 中 SOAP 类组织过程的具体情况,我们必须将复杂对象包装在 SoapVar 类中。否则,对象将无法正确编码,也无法在远程 SOAP 处理程序上加载。
函数 "getAsSoap" 调用对要传输的对象进行编码。编码后,它可以正确传输。
*/
abstract class SOAPable {
public function getAsSOAP() {
foreach($this as $key=>&$value) {
$this->prepareSOAPrecursive($this->$key);
}
return $this;
}
private function prepareSOAPrecursive(&$element) {
if(is_array($element)) {
foreach($element as $key=>&$val) {
$this->prepareSOAPrecursive($val);
}
$element=new SoapVar($element,SOAP_ENC_ARRAY);
}elseif(is_object($element)) {
if($element instanceof SOAPable) {
$element->getAsSOAP();
}
$element=new SoapVar($element,SOAP_ENC_OBJECT);
}
}
}
// ------------------------------------------
// 抽象示例
// ------------------------------------------
class PersonList extends SOAPable {
protected $ArrayOfPerson; // 变量必须是受保护的或公开的!
}
class Person extends SOAPable {
// 任何数据
}
$client=new SoapClient("test.wsdl", array( 'soap_version'=>SOAP_1_2, 'trace'=>1, 'classmap' => array('Person' => "Person", 'PersonList' => "PersonList") ));
$PersonList=new PersonList;
// 一些操作
$PersonList->getAsSOAP();
$client->someMethod($PersonList);
?>
因此,每个将通过 SOAP 传输的类都必须扩展自 SOAPable 类。
如您所见,在上面的代码中,函数 prepareSOAPrecursive 在父对象或数组中搜索另一个嵌套对象,如果找到,则尝试调用函数 getAsSOAP() 来准备嵌套对象,然后简单地通过 SoapVar 类包装。
因此,在代码传输之前,只需调用 $obj->getAsSOAP()