Zend SOAP:在WSDL中将缺省数组元素名称“item”更改为复杂类型的类名称

问题描述:

可能会提出这个问题,但搜索起来很困难,我找不到任何有关它的信息。再加上它不容易问。Zend SOAP:在WSDL中将缺省数组元素名称“item”更改为复杂类型的类名称

我正在使用Zend SOAP的自动发现重新创建我们的旧SOAP接口(因为切换到微服务和重新工作的一切)。

到目前为止,它的工作就像一个魅力。但是在使用列表/数组时,我在重新创建一些服务的SOAP响应时遇到了一个问题。

SOAP请求的旧响应XML看起来像这样。它包含<SMSEntries>列表中的两个<SMSEntry>

<SOAP-ENV:Envelope> 
    <SOAP-ENV:Body> 
     <ns1:getSMSByTimeSpanResult> 
     <AmountOfEntries>2</AmountOfEntries> 
     <SMSEntries> 
      <SMSEntry></SMSEntry> 
      <SMSEntry></SMSEntry> 
     </SMSEntries> 
     </ns1:getSMSByTimeSpanResult> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

但重新创建的响应看起来像这样。它包含<SMSentries>列表中的SMSEntry类型的两个<item>

<SOAP-ENV:Envelope> 
    <SOAP-ENV:Body> 
     <ns1:getSMSByTimeSpanResponse> 
     <return xsi:type="ns1:getSMSByTimeSpanResponse"> 
      <AmountOfEntries xsi:type="xsd:int">2</AmountOfEntries> 
      <SMSEntries SOAP-ENC:arrayType="ns1:SMSEntry[2]" xsi:type="ns1:ArrayOfSMSEntry"> 
       <item xsi:type="ns1:SMSEntry"></item> 
       <item xsi:type="ns1:SMSEntry"></item> 
      </SMSEntries> 
      <DataEx xsi:nil="true"/> 
     </return> 
     </ns1:getSMSByTimeSpanResponse> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

我无法控制客户。他们可能正在通过比较字符串来检查SMSEntry。我想使用类名称SMSEntry作为XML标签名称。

二,我想省略其他的东西,包装一切,<return>标签。

我使用这样的自动发现:

use Zend\Soap\AutoDiscover; 
use Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeComplex; 

$autoDiscover = new AutoDiscover(new ArrayOfTypeComplex()); 
$autoDiscover->setClass(new Standard($sm)); 

的getSMSByTimeSpanResponse的定义是这样的:

Standard.php

/** 
* Class getSMSByTimeSpanResponse 
* 
* @package LgxServiceManager\Service 
*/ 
class getSMSByTimeSpanResponse 
{ 
    /** 
    * @var int 
    */ 
    public $AmountOfEntries; 

    /** 
    * @var \LgxServiceManager\Service\SMSEntry[] 
    */ 
    public $SMSEntries; 
} 

/** 
* Class SMSEntry 
* 
* @package LgxServiceManager\Service 
*/ 
class SMSEntry 
{ 
} 

有谁知道如何任何想法这个?

我发现一些代码在library\Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeSequence.php:122_addSequenceType()一种方法是设置硬编码的属性:

$element->setAttribute('name', 'item'); 

但这式“序列”不输入“情结”就像我使用...

谢谢你在前进, 菲利普


\ ED IT

天哪......我只是发现了另一种结构,我不知道如何与Zend的SOAP的自动发现创建...

<mainMember1>SERIALNUMBER</mainMember1> 
<mainMember2>NAMEOFPRODUCT</mainMember2> 
<mainMember3>000000-000-0</mainMember3> 
<Rules> 
    <RuleEntry> 
     <singleValue>allow</singleValue> 
     <ResourceList> 
      <Name>generic</Name> 
      <ResourceEntry>[...]</ResourceEntry> 
      <ResourceEntry>[...]</ResourceEntry> 
      <ResourceEntry>[...]</ResourceEntry> 
     </ResourceList> 
     <ResourceList> 
      <Name>default</Name> 
      <ResourceEntry>[...]</ResourceEntry> 
      <ResourceEntry>[...]</ResourceEntry> 
      <ResourceEntry>[...]</ResourceEntry> 
     </ResourceList> 
    </RuleEntry> 
</Rules> 

正如你可以看到,里面有一个在<singleValue><RuleEntry>但是多个<ResourceList> s。资源列表中使用相同的结构:一个<Name>和多个<ResourceEntry> ...

这甚至可以用自动发现来处理吗?

+1

这也许给你一些提示:http://*.com/questions/17307571/zend-framework-2-soap-autodiscover-and-complex-types –

+1

谢谢。我自己想出了这个问题,并且已经按照我的问题代码中所描述的那样使用它。我的WSDL看起来非常好。但是,XML的响应要比那些“item”元素... –

+0

无论答案如何,我都感到你的痛苦。任何时候任何人都应该暗示使用SOAP,你必须非常快速地喊“使用REST!”在他们身上。 – icc97

对任何人来说仍具有上述的问题:stdClass()这样 默认响应:

$array = ['lets', 'test', 'it']; 
$response = new stdClass(); 
$response->results = $array; 

会像:

<return xsi:type="SOAP-ENC:Struct"> 
    <results SOAP-ENC:arrayType="xsd:string[3]" xsi:type="SOAP-ENC:Array"> 
     <item xsi:type="xsd:string">lets</item> 
     <item xsi:type="xsd:string">test</item> 
     <item xsi:type="xsd:string">it</item> 
    </results> 
</return> 

我们能做什么 - 我们可以改变数组ArrayObject()

$array = ['lets', 'test', 'it']; 

    $response = new stdClass(); 
    $response->results = new ArrayObject(); 
    foreach($array as $item) { 
     $response->results->append($item); 
    } 

哪个返回:

  <return xsi:type="SOAP-ENC:Struct"> 
      <results xsi:type="SOAP-ENC:Struct"> 
       <BOGUS xsi:type="xsd:string">lets</BOGUS> 
       <BOGUS xsi:type="xsd:string">test</BOGUS> 
       <BOGUS xsi:type="xsd:string">it</BOGUS> 
      </results> 
     </return> 

最后蛋糕上的糖霜:

$array = ['lets', 'test', 'it']; 

$response = new stdClass(); 
$response->results = new ArrayObject(); 
foreach($array as $item) { 
    $soapVar = new SoapVar($item,XSD_STRING,NULL,NULL,'result'); 
    $response->results->append($soapVar); 
} 

它将返回:

<return xsi:type="SOAP-ENC:Struct"> 
    <results xsi:type="SOAP-ENC:Struct"> 
     <result xsi:type="xsd:string">lets</result> 
     <result xsi:type="xsd:string">test</result> 
     <result xsi:type="xsd:string">it</result> 
    </results> 
</return> 

正如你可以看到第五个参数告诉这将是XML元素的关键。你也需要知道第二个参数,因为它告诉哪个是变量的类型。你可以找到更多在这里: https://secure.php.net/manual/en/class.soapvar.php