简体   繁体   English

PHP Soap Client:如何使用Derived类作为参数调用WebService?

[英]PHP Soap Client: How call WebService with Derived class as parameter?

I'm using PHP 5, and want to call a webservice that is defined sort of like this: 我正在使用PHP 5,并且想调用定义如下的Web服务:

webmethod ( AbstractBase obj );

I'm using a SoapClient (wsdl-based). 我正在使用SoapClient (基于wsdl)。 The web method is expecting a subclass of AbstractBase. Web方法需要AbstractBase的子类 Yet, in PHP, calling the soap method gets me this error: 但是,在PHP中,调用soap方法会使我遇到此错误:

Server was unable to read request. 
        ---> There is an error in XML document  
        ---> The specified type is abstract: name='AbstractBase'

I'm pretty sure the problem is I have to specify the type of the obj parameter in the Soap call - but I can't seem to find the magic word to make it so. 我很确定问题是我必须在Soap调用中指定obj参数的类型-但我似乎找不到使它如此的魔术字。

    $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);

That was a good suggestion, but it didn't work either. 这是一个很好的建议,但也没有用。 But it got me going in the right direction. 但这使我朝着正确的方向前进。 I took your idea, created the 2 classes, and tried to explicitly set the type of the object with a SoapVar and XSD_ANYTYPE. 我接受了您的想法,创建了2个类,并尝试使用SoapVar和XSD_ANYTYPE显式设置对象的类型。 That almost worked - but it did not set the name space (ns1:) on the fields in the class. 几乎可以正常工作-但它没有在类的字段中设置名称空间(ns1 :)。

SO how did I eventually fix this? 所以我最终如何解决这个问题? It took 2 things. 花了两件事。

I discovered the wonderful XSD_ANYXML . 我发现了很棒的XSD_ANYXML This lets me roll my own XML for the request. 这使我可以为请求滚动自己的XML。 By itself it failed to add the xsi namespace to the soap envelope. 它本身无法将xsi名称空间添加到soap信封。 So I had to force one parameter to be an XSD_STRING to wake up the code that was building the request. 因此,我必须强制一个参数为XSD_STRING才能唤醒正在构建请求的代码。 My working code is: 我的工作代码是:

$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);

I wonder if the array you are passing (instead of an object) is being cast into AbstractBase somewhere and the error is being thrown then. 我想知道您正在传递的数组(而不是对象)是否被投射到某个地方的AbstractBase中,然后引发了错误。 You might need to pass an actual object instead: 您可能需要传递一个实际对象:

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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM