PHP Soap客户端:如何使用派生类作为参数调用WebService?

PHP Soap客户端:如何使用派生类作为参数调用WebService?,php,web-services,soap,Php,Web Services,Soap,我使用的是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 typ

我使用的是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'
我想知道您正在传递的数组(而不是对象)是否正在被转换到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);

那是个好建议,但也不管用。但这让我走上了正确的方向。我接受了您的想法,创建了两个类,并尝试使用SoapVar和XSD_ANYTYPE显式设置对象的类型。这几乎奏效了——但它没有在类中的字段上设置名称空间(ns1:)

那么我最终是如何解决这个问题的呢?花了两件事

我发现了奇妙的XSD\u ANYXML。这使我能够为请求滚动自己的XML。它本身无法将xsi名称空间添加到soap信封中。因此,我必须强制一个参数为XSD_字符串,以唤醒生成请求的代码。我的工作代码是:

$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);
$client=newsoapclient($WSDL,$soapSettings);
$myXml=”
$internalId
$externalId
";
$params=数组(
//这是在头中强制使用XSI名称空间所必需的(必须有更好的方法)
'foo'=>newsoapvar('bar',XSD_STRING',STRING,'http://www.w3.org/2001/XMLSchema-instance'),
//这使用了我创建的XML
'obj'=>新的SoapVar($myXml,XSD_ANYXML),
);
$response=$client->webmethod($params);

ahhh!!!如果我能给你我所有的代表点,我会的。经过一整天的搜索,我相信这是你能在互联网上找到这些信息的唯一地方。救了我。使用
XSD\u ANYXML
似乎是一个相当丑陋的解决办法。SoapVar()采用
$type\u名称
$type\u名称空间
,这两个名称空间都是为了这样的目的而存在的。
$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);