PHP SoapClient creating XML references for identical elements, makes it unacceptable for service

899

I am working on a SOAP client in PHP, and the calls are going through to the service fine, with the exception of calls where there are elements that are identical to each other. It seems that when this happens, rather than creating two separate but identical elements, like this:

<ns1:someelement>
  <ns1:name>name1</ns1:name>
  <ns1:value>value1</ns1:value>
</ns1:someelement>
<ns1:someelement>
  <ns1:name>name1</ns1:name>
  <ns1:value>value1</ns1:value>
</ns1:someelement>

it is insisting on making only one copy of the element and assigning it an ID, and using href for any subsequent instances of that element (shown below), which is not supported by the webservice I am using (I don't know why this is, but it doesn't really matter because I cannot change it)

<ns1:someelement id="#ref1">
  <ns1:name>name1</ns1:name>
  <ns1:value>value1</ns1:value>
</ns1:someelement>
<ns1:someelement href="#ref1" />

So my question is how might I force the XML to come out with the duplicate elements included in full, rather than them using hrefs/ids. I checked the docs for PHP SoapClient for an option or something of the sort, but couldn't find anything. Any help or advice would be greatly appreciated. Thanks.

865

Answer

Solution:

SoapClient makes a reference only when you use the same object on multiple XML nodes. Make for each place a new object if you do not want the references.

916

Answer

Solution:

In your PHP code make a property with unique index so the resulting XML will look like:

<ns1:someelement>
  <ns1:name>name1</ns1:name>
  <ns1:value>value1</ns1:value>
  <ns1:index>0</ns1:value>
</ns1:someelement>
<ns1:someelement>
  <ns1:name>name1</ns1:name>
  <ns1:value>value1</ns1:value>
  <ns1:index>1</ns1:value>
</ns1:someelement>

Then PHP SoapClient will not make href references to the same copies of data and web service successfully ignored these unique fields in my case. No, I do not pass the same fields of someelement as reference in PHP code. They are cloned, however PHP SoapClient is smart enough to zip their multiple occurencies as references, unfortunately.

269

Answer

Solution:

  • Make sure not use references
  • Try to add params manually withSoapParam
  • Try to add params manually withSoapVar

$soapClient->__soapCall('Method', array(
    new SoapParam($someelement1, 'someelement'),
    // or
    new SoapVar('<ns1:someelement><ns1:name>name1</ns1:name><ns1:value>value1</ns1:value></ns1:someelement>', XSD_ANYXML)
));
713

Answer

Solution:

Hello You can try this fix:

You need to extends the SoapClient and fix the generated request:

You need to add the tags that are causing problems here

$tags = ['Tag1', 'Tag2', 'Tag3'];

And then use the MySoapClient instead of SoapClient

class MySoapClient extends SoapClient {

public function __construct($a, $b){
    parent::__construct($a, $b);
}

public function __doRequest($request, $location, $action, $version, $one_way = 0) {

    $tags = ['Tag1', 'Tag2', 'Tag3'];
    foreach($tags as $tag){
        if (preg_match("~<ns1:{$tag} id=\"ref(.+)\">(.+)</ns1:{$tag}>~ismU", $request, $matches)) {
            $ref = $matches[1];

            $request = str_replace([' id="ref'.$ref.'"'], '', $request);

            $tagValue = "<ns1:{$tag}>{$matches[2]}</ns1:{$tag}>";
            $request = str_replace("<ns1:{$tag} href=\"#ref{$ref}\"/>", $tagValue, $request);
        }
    }
    return parent::__doRequest($request, $location, $action, $version);
}

}

People are also looking for solutions to the problem: php - Replace a value in object array

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.