不再解析 SOAP 响应(可能在添加命名空间之后)

SOAP response is not parsed anymore (maybe after adding namespace)

我们正在与网上商店的 ERP 界面进行通信。 ERP部分升级了

现在不再正确解析响应。

我在 WSDL 模式下使用 PHP SOAP 客户端。

protected function getSoapClient()
{
    $context = // ...

    $client = new \SoapClient($this->url . '?wsdl', [
        'trace' => true,
        'stream_context'  => $context,
        // 'uri' => 'urn:example-org:WebshopService',
    ]);

    return $client;
}

$client = $this->getSoapClient();
$response = $client->placeOrder($placeOrder);

使用 getLastResponse 我看到以下结果:

$client->__getLastResponse();
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                          xmlns:web="urn:example-org:WebshopService">
            <soapenv:Header/>
            <soapenv:Body>
                <web:placeOrderResponse>
                    <web:result>OK</web:result>
                </web:placeOrderResponse>
            </soapenv:Body>
        </soapenv:Envelope>
    </soap:Body>
</soap:Envelope>

在早期版本的 ERP 系统中它可以工作,$response\StdClass 的一个实例。现在 $responsenull.

我相信这是因为在结果中引入了命名空间。

我尝试添加行

 'uri' => 'urn:example-org:WebshopService',

到 SOAP 配置,但没有帮助。

这可能是结果的解析问题?如何修复?当然,我可以简单地查看跟踪的最后响应,但我相信如果 SOAP 客户端正确解析结果,会有更好的解决方案。

根据 PiTheNumber 的回答我也试过了

'soap_version' => SOAP_1_2,

但是越来越

 A SOAP 1.2 message is not valid when sent to a SOAP 1.1 only endpoint.  

使用时

 'uri' => 'http://schemas.xmlsoap.org/soap/envelope/',

响应仍然为空。

也许我的 WSDL 是错误的...

<schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="urn:example-org" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:prodata="urn:schemas-progress-com:xml-prodata:0001" xmlns:S2="urn:example-org:WebshopService" xmlns:S1="urn:soap-fault:details" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="urn:example-org:WebshopService">
  <element name="placeOrder">
    <complexType>
      <sequence>
    <element name="pcRequest" nillable="true" type="xsd:string"/>
    <element name="gpcBCR_Connection_Obj" nillable="true" type="xsd:string"/>
      </sequence>
    </complexType>
  </element>
  <element name="placeOrderResponse">
    <complexType>
      <sequence>
    <element name="result" nillable="true" type="xsd:string"/>
      </sequence>
    </complexType>
  </element>
</schema>

编辑2:

我找到了 并检查了 WSDL 是否将 return 值定义为 void,它没有:

var_dump($client->__getFunctions());

Returns

array(1) {
  [0]=>
  string(53) "placeOrderResponse placeOrder(placeOrder 
$parameters)"
}

编辑 3:

我试过其他东西:

我使用 ReadyAPI 试用版根据我从实际 ERP 收到的 WSDL 模拟 SOAP API。

当我做你的时候,结果是这样的:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:proalpha-org:WebshopService">
   <soapenv:Header/>
   <soapenv:Body>
      <urn:placeOrderResponse>
     <urn:result>OK</urn:result>
      </urn:placeOrderResponse>
   </soapenv:Body>
</soapenv:Envelope>

PHP正确解析了。

这是差异:

那么 WSDL 不是 100% 正确还是为不同的解释留下了空间?

SOAP服务器有问题吗?是否违反标准?或者这是 PHP Soap 客户端中的错误?

https://www.ibm.com/docs/en/cics-ts/5.4?topic=format-structure-soap-message 读起来像

The SOAP envelope The SOAP is the root element in every SOAP message. It contains two child elements, an optional , and a mandatory > .

所以 envolpe 应该只作为 root 出现一次,而不是两次?

试试这个

$client = new \SoapClient(null, [
    'trace' => true,
    'stream_context'  => $context,
    // 'uri' => 'urn:example-org:WebshopService',
    'location' => $this->url . '?wsdl',
    'uri' => 'http://schemas.xmlsoap.org/soap/envelope/',
    # maybe? 'soap_version' => SOAP_1_2,
]);

原来这是 ERP 上的错误。

重复的信封导致了问题,这不是故意的。 它已在 ERP 端修复,现在解析工作完美无缺,无需对 PHP-代码进行任何调整。