我正在使用PHP 5,并希望调用定义如下的Web服务:
webmethod ( AbstractBase obj );
我正在使用 SoapClient (基于wsdl)。 Web方法期待AbstractBase的子类。然而,在PHP中,调用soap方法会给我带来这个错误:
Server was unable to read request. ---> There is an error in XML document ---> The specified type is abstract: name='AbstractBase'
我很确定问题是我必须在Soap调用中指定 obj 参数的类型 - 但我似乎无法找到神奇的词来实现它。< / p>
$client = new SoapClient($WSDL, $soapSettings);
$obj = array(
'internal_id' => $internalId,
'external_id' => $externald,
);
$params = array(
'obj' => $obj // How do I say it is of type: DerivedClass?
);
$response = $client->webmethod($params);
答案 0 :(得分:5)
这是一个很好的建议,但它也没有用。但它让我朝着正确的方向前进。我接受了你的想法,创建了2个类,并尝试使用SoapVar和XSD_ANYTYPE显式设置对象的类型。这几乎可以工作 - 但它没有在类中的字段上设置名称空间(ns1 :)。
所以我最终如何解决这个问题?它花了两件事。
我发现了精彩的 XSD_ANYXML 。这让我可以为请求滚动自己的XML。它本身无法将xsi名称空间添加到soap信封中。所以我不得不强制一个参数成为XSD_STRING来唤醒正在构建请求的代码。我的工作代码是:
$client = new SoapClient($WSDL, $soapSettings);
$myXml = "
<ns1:obj xsi:type='ns1:DerivedClass'>
<ns1:internal_id>$internalId</ns1:internal_id>
<ns1:external_id>$externalId</ns1:external_id>
</ns1:obj>
";
$params = array(
// this is needed to force the XSI namespace in the header (there must be a better way)
'foo' => new SoapVar('bar', XSD_STRING, 'String, 'http://www.w3.org/2001/XMLSchema-instance'),
// this uses the XML I created
'obj' => new SoapVar($myXml, XSD_ANYXML),
);
$response = $client->webmethod($params);
答案 1 :(得分:0)
我想知道您传递的数组(而不是对象)是否正在某处投射到AbstractBase中,然后抛出错误。您可能需要传递实际对象:
abstract class AbstractBase {
public $internal_id;
public $external_id;
}
class DerivedClass extends AbstractBase { }
$obj = new DerivedClass();
$obj->internal_id = $internalId;
$obj->external_id = $externalId;
$params = array(
'obj' => $obj // Now an instance of DerivedClass
);
$response = $client->webmethod($params);