Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between SoapVar and SoapParam?

In PHP, we have SoapVar and SoapParam classes. I've been confused long enough, since there is no decent documentation of them on php.net.

Today I was surprised to find out that those lines will produce the exact same result in the XML input:

$soapVar   = new SoapVar((object) ['Foo' => 'bar'], null, null, null, 'TagName');
$soapParam = new SoapParam((object) ['Foo' => 'bar'], 'TagName');

In most SoapClient tutorials, I have seen snippets with SoapParam inside SoapVar whenever someone wanted to set custom xsi:type:

$response = $soapClient->DoSomething(
    new SoapParam(
        new SoapVar(
            (object) ['Foo' => 'bar'],
            null,
            'TypeName'
        ),
        'TagName'
    )
);

That is really unintuitive, since SoapVar and SoapParam class names don't say much. The same result can be achieved by more elegant:

$response = $soapClient->DoSomething(
    new SoapVar(
        (object) ['Foo' => 'bar'],
        null,
        'TypeName',
        null,
        'TagName'
    )
);

What is the purpose of SoapParam then? Is it just more simple version of SoapVar? It seems like these two are confused and misunderstood a lot. Is there any extra behavior attached to SoapParam?

like image 394
Robo Robok Avatar asked Mar 15 '17 00:03

Robo Robok


1 Answers

You are right the manual is a little vague explaining the exact difference in theory and I was surprised that till now none had pointed some detailed info or explanation into their differences.

By the manual

SoapParam:

Represents parameter to a SOAP call.

SoapVal:

A class representing a variable or object for use with SOAP services.

I went a little down and the main difference I could find was the data parameter in their representative constructors:

for SoapParam::SoapParam ( mixed $data , string $name ) where $data =

The data to pass or return. This parameter can be passed directly as PHP value, but in this case it will be named as paramN and the SOAP service may not understand it.

while on the other hand we have SoapVar::SoapVar ( mixed $data , string $encoding [, string $type_name [, string $type_namespace [, string $node_name [, string $node_namespace ]]]] ) where $data =

The data to pass or return.

By taking these two into consideration, the example in the PHP Manual, i believe points for good the main difference in the argument passing and what you can do with one that can not be done with the other.

In the case of SoapParam

<?php
$client = new SoapClient(null,array('location' => "http://localhost/soap.php",
                                    'uri'      => "http://test-uri/"));
$client->SomeFunction(new SoapParam($a, "a"),
                      new SoapParam($b, "b"),
                      new SoapParam($c, "c"));
?>

where $a, $b and $c are PHP variables send directly without passing them through a structure / class. The SaopParam constructor is getting the parameter $data (PHP Variable) and the String representative of the parameter name.

On the other side SoapVar

<?php
class SOAPStruct {
    function SOAPStruct($s, $i, $f) 
    {
        $this->varString = $s;
        $this->varInt = $i;
        $this->varFloat = $f;
    }
}
$client = new SoapClient(null, array('location' => "http://localhost/soap.php",
                                     'uri'      => "http://test-uri/"));
$struct = new SOAPStruct('arg', 34, 325.325);
$soapstruct = new SoapVar($struct, SOAP_ENC_OBJECT, "SOAPStruct", "http://soapinterop.org/xsd");
$client->echoStruct(new SoapParam($soapstruct, "inputStruct"));
?>

As you can see, the arguments/variables are passed through the per-defined class and after an object of that class is passed as argument. That Class is a representative of the SOAP Structure (that SOAP can recognize / thous the risk with SoapParam).

Now the almost confusing part...although there are a few differences in the constructor why the same behavior on your example?

$soapVar   = new SoapVar((object) ['Foo' => 'bar'], null, null, null, 'TagName');
$soapParam = new SoapParam((object) ['Foo' => 'bar'], 'TagName');

I am not surprised, as mentioned above the data either a SOAP Structure or a PHP Variable of a CORRECT Soap Structure is the same :) thanks to Object Oriented we pass the Object produced by a PHP Class. In the SoapVar the construction of the object has more options, thus allowing the user to adapt a more "safe" request towards the SOAP call. While on SoapParam the object can be constructed by passing any object and next its name.

Your (object) ['Foo' => 'bar'] is very simple and has no need for XML Schema Encoding thus the SOAP call receiving it I believe can very easily understand it. It has no need for the

  • encoding

The encoding ID, one of the XSD_... constants.

that is the second parameter in the SoapVar constructor.

Finally since they both accept an object (any object) in place of the $data variable to my understanding the SoapVar just gives the possibility to build a more safer request to be understood by the SOAP call through the extra arguments in the constructor. The SoapParam is just a badass and allows you to send anything you like at the risk of the SOAP refusing it.... it's like almost wants to act as JSON @ RESTful :P not caring about the type nor structure of the data it sends :)

References:

  • SoapParam Class
  • SoapParam Constructor
  • SoapVar Class
  • SoapVar Constructor
like image 168
oetoni Avatar answered Oct 16 '22 00:10

oetoni