skip to Main Content

We are communication with an ERP interface from a Webshop. The ERP part got upgraded.

Now the response is not parsed properly anymore.

I am using the PHP SOAP client in WSDL mode.

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

Using getLastResponse I see the following result:

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

In an earlier version of the ERP system it worked and $response was an instance of StdClass. Now $response is null.

I believe this is because the namespaces were introduced in the result.

I tried adding the line

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

to the SOAP config but it did not help.

Is this likely a parsing problem of the result? How can it be fixed? Of course I could simple look into last response from the trace, but I believe a better solution would be if the SOAP client parses the result properly.

As per PiTheNumber’s answer I also tried

'soap_version' => SOAP_1_2,

But getting

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

When using

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

response is still null.

maybe my WSDL is wrong … https://stackoverflow.com/a/26056248/288568

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

Edit2:

I found https://stackoverflow.com/a/22717640/288568 and checked whether the WSDL defined the return value as void, it doesn’t:

var_dump($client->__getFunctions());

Returns

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

EDIT3:

I tried somthing else:

I used the ReadyAPI trial version to mock the SOAP API based on the WSDL I receive from the actual ERP.

When I do you, the result looks like this:

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

Which is properly parsed by PHP.

This is the Diff:

ERP Response (Left) vs Mock Response

So either the WSDL is not 100% correct or leaves room for different interpretation?

Is there something wrong with the SOAP server? Is it violating standards? Or is this a bug in the PHP Soap client?

https://www.ibm.com/docs/en/cics-ts/5.4?topic=format-structure-soap-message reads like

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

So it seams the envolpe should only appear once as root, not twice?

2

Answers


  1. Chosen as BEST ANSWER

    Turn's out it was a bug on the ERP.

    The duplicate envelope caused the problem and was not intended. It was fixed on the ERP side and now the parsing works flawlessly without any adaption to the PHP-code.


  2. Try this

    $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,
    ]);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search