Geaux Virtual

Helping virtualize the datacenter…

Using PHP5 SOAP with vSphere API

with 3 comments

I will more blog later detailing better usage of PHP with vSphere API.  This post is focused on how to use PHP5 Soap Client methods to interact with the vSphere API.

The vSphere API is SOAP based.  First step is to download the WSDL from vCenter or the ESX(i) host.  So how do we do this with PHP5?

First, we need a SOAP Client.

$connection = new SoapClient(“https://<hostname or ip/sdk/vimService.wsdl”, array(“trace” => 1, “location”=>”https://<hostname or ip>/sdk/”);

From this code snippet, we created a new SoapClient, $connection, set the location of the wsdl, set trace to 1 for debugging purposes, and set the location that we will send requests to.  Next we need to create a SOAP message to send to the server.

$soapmsg[“_this”] = new SoapVar(“ServiceInstance”, XSD_STRING, “ServiceInstance”);

Basically every call to vSphere API will require a “_this” key.  Most calls will require more information.  From this code snippet, we are creating an array with a “_this” key and setting a SoapVar with data of “ServiceInstance” and type of “ServiceInstance”.  Now, we are going to retrieve the Service Instance.

$result = $connection->RetrieveServiceContent($soapmsg);

And what do we get?  Definitely not the result we were expecting.  With trace enabled, we can actually view the SOAP request that was made to the server.

var_dump($connection->__getLastRequest());

What is the problem with the SOAP request?  Well, PHP5 SOAP function sets the type of the SOAP message as “xsi:type”.  The vSphere API expects a type of just “type”.  How do we fix this?  We must create our own class that extends SoapClient and overrides the __doRequest method.  Here, we can strip “xsi:” out of the request and send the vSphere API the request it is expecting.

class mySoapClient extends SoapClient {

     function __doRequest($request, $location, $action, $version) {

          $request = str_replace(“xsi:”, “”, $request);

          return parent::__doRequest($request, $location, $action, $version);

     }

}

After altering the request, we can now successfully retrieve the Service Instance from the vSphere API.

Advertisements

Written by jguidroz

October 7, 2010 at 7:22 am

Posted in Scripting, VMware

3 Responses

Subscribe to comments with RSS.

  1. Thank you for your article. SOAP::Lite Perl lib has the same behaviour. For those who care, I did this hack to avoid the issue:

    sub log_message {
    my ($in) = @_;
    if (ref($in) eq ‘HTTP::Request’) {
    $in->{_content} =~ s/ xsi:type=”urn:vim25:/ type=”/;
    $in->{‘content-length’} = length ($in->{_content} );
    }
    }
    use SOAP::Lite +trace => [ transport => \&log_message ];

    Gonéri

    January 25, 2011 at 3:22 pm

  2. Thanks for this example, it really helped me out. Most other examples are using nusoap and I was trying to avoid using it.

    Keep it up!

    bwalkingson

    April 16, 2011 at 9:00 pm

  3. Hy, can you give an example of how a vsphere array of data objects should be packed with SoapVar so the request will be valid? I’m trying to call a method the requires as parameters data objects that have arrays of data objects, and request fails saying that some fields are not present, although I do send them, so it must be the way they are packed.
    Thx

    Victor

    March 25, 2012 at 2:51 am


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: