Php 为什么在文档/文字样式中使用WSDL的SoapClient返回带有额外键元素的数组?

Php 为什么在文档/文字样式中使用WSDL的SoapClient返回带有额外键元素的数组?,php,soap,wsdl,Php,Soap,Wsdl,我们正在将RPC/编码的Web服务转换为document/literal/wrapped。 WSDL(使用nusoap)已经重写为使用新格式 我使用PHP SoapClient的方式如下: new SoapClient($wsdlUrl, array( 'cache_wsdl' => WSDL_CACHE_NONE, 'trace' => true, 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, )); <?

我们正在将RPC/编码的Web服务转换为document/literal/wrapped。 WSDL(使用nusoap)已经重写为使用新格式

我使用PHP SoapClient的方式如下:

new SoapClient($wsdlUrl, array(
    'cache_wsdl' => WSDL_CACHE_NONE,
    'trace' => true,
    'features' => SOAP_SINGLE_ELEMENT_ARRAYS,
));
<?xml version="1.0" encoding="utf-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Body>
    <some_functionResponse xmlns="urn:toets_nl_wsdl">
      <messages xmlns="">
        <item>foo</item>
        <item>bar</item>
      </messages>
    </some_functionResponse>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
stdClass Object
(
    [messages] => stdClass Object
        (
            [item] => Array             // <-- here
                (
                    [0] => foo
                    [1] => bar
                )

        )

)
相关的WSDL部分如下所示(应遵循WS-I基本概要):


当我提交请求时,XML响应如下所示:

new SoapClient($wsdlUrl, array(
    'cache_wsdl' => WSDL_CACHE_NONE,
    'trace' => true,
    'features' => SOAP_SINGLE_ELEMENT_ARRAYS,
));
<?xml version="1.0" encoding="utf-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Body>
    <some_functionResponse xmlns="urn:toets_nl_wsdl">
      <messages xmlns="">
        <item>foo</item>
        <item>bar</item>
      </messages>
    </some_functionResponse>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
stdClass Object
(
    [messages] => stdClass Object
        (
            [item] => Array             // <-- here
                (
                    [0] => foo
                    [1] => bar
                )

        )

)

福
酒吧
在PHP中转储结果对象时,它如下所示:

new SoapClient($wsdlUrl, array(
    'cache_wsdl' => WSDL_CACHE_NONE,
    'trace' => true,
    'features' => SOAP_SINGLE_ELEMENT_ARRAYS,
));
<?xml version="1.0" encoding="utf-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Body>
    <some_functionResponse xmlns="urn:toets_nl_wsdl">
      <messages xmlns="">
        <item>foo</item>
        <item>bar</item>
      </messages>
    </some_functionResponse>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
stdClass Object
(
    [messages] => stdClass Object
        (
            [item] => Array             // <-- here
                (
                    [0] => foo
                    [1] => bar
                )

        )

)
stdClass对象
(
[消息]=>stdClass对象
(
[项目]=>数组//foo
[1] =>巴
)
)
)
为什么在结果树中有一个额外的元素“item”?当我们仍然使用RPC/encoded时,就不存在这种情况


处理响应时是否有方法删除该元素?

您完全确定WSDL定义中没有指定该元素吗?我确信服务器添加额外的元素不是为了好玩:)

或者,这可能是文档编码样式的结果

当返回数组类型的内容时,元素在sapwebservices(我经常使用)中非常常见,但正如我上面所写的,它在WSDL中明确指定

您还可能发现,当数组只有一个元素时,将不是数组,因此请在代码中使用

if(!is_array($messages->item)) {
    $messages->item = array($messages->item);
}

您的WSDL清楚地表明,存在一个包含字符串(也称为数组)的项目,其出现次数不限。所以PHP只是向您呈现WSDL中描述的结构,以及服务器返回的结构

我看不出有什么不对劲。不要仅仅因为Soap和RPC的功能相同就期望它与RPC相同。如果您不希望该项元素出现,请更改WSDL和服务,但这可能比将PHP客户机代码适应新的数据结构更困难


您甚至使用了SOAP单元素数组,这是避免检查元素是否真的是数组的一件好事。

您能发布WSDL和模式吗?当您仍然使用RPC/encoded时,它是什么样子的?当只有一个项时,PHP Soap有一个选项Soap\u SINGLE\u ELEMENT\u ARRAYS以防止您描述的行为。是的,“项”名称在WSDL中(也在消息中)。当你想在文档/文字中使用数组时,也许这就是你得到的结果,但我希望我遗漏了一些东西。我从来没有注意到SOAP\u单元素\u数组!谢谢你。我一直认为是服务器决定了它:)WSDL数组是根据WS-I规范构建的,我认为这是这里的授权源?(). 我看到PHP只是简单地逐字地解析它,我认为它在检测这个数组结构时可能“更聪明”。其他(可能更成熟的)SOAP客户机(在其他语言中)是否也以同样的方式处理此问题?其他语言提供了不同的变量结构,可能能够更好地处理这种情况,但PHP只能提供数组或对象,而SOAP客户机本身也必须将此类数据结构来回映射到XML。做“智能”优化是错误的——这就是为什么你有SOAP\u单元素\u数组,它在不同的层次上禁用了这种“智能”行为。斯文,你找到解决问题的方法了吗?