Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a PHP SOAP call using the SoapClient class

Tags:

php

soap

People also ask

How can make SOAP call in PHP?

To make SOAP requests to the SOAP API endpoint, use the "Content-Type: application/soap+xml" request header, which tells the server that the request body contains a SOAP envelope. The server informs the client that it has returned a SOAP envelope with a "Content-Type: application/soap+xml" response header.

What is SoapClient?

A SOAP client formulates a request for a service. This involves creating a conforming XML document, either explicitly or using Oracle SOAP client API. A SOAP client sends the XML document to a SOAP server. This SOAP request is posted using HTTP or HTTPS to a SOAP Request Handler running as a servlet on a Web server.

What is __ Soapcall?

This is a low level API function that is used to make a SOAP call. Usually, in WSDL mode, SOAP functions can be called as methods of the SoapClient object. This method is useful in non-WSDL mode when soapaction is unknown, uri differs from the default or when sending and/or receiving SOAP Headers.

What is SOAP protocol in PHP?

SOAP stands for Simple Object Access Protocol. SOAP is an application communication protocol. SOAP is a format for sending and receiving messages. SOAP is platform independent.


This is what you need to do.

I tried to recreate the situation...


  • For this example, I created a .NET sample WebService (WS) with a WebMethod called Function1 expecting the following params:

Function1(Contact Contact, string description, int amount)

  • Where Contact is just a model that has getters and setters for id and name like in your case.

  • You can download the .NET sample WS at:

https://www.dropbox.com/s/6pz1w94a52o5xah/11593623.zip


The code.

This is what you need to do at PHP side:

(Tested and working)

<?php
// Create Contact class
class Contact {
    public function __construct($id, $name) 
    {
        $this->id = $id;
        $this->name = $name;
    }
}

// Initialize WS with the WSDL
$client = new SoapClient("http://localhost:10139/Service1.asmx?wsdl");

// Create Contact obj
$contact = new Contact(100, "John");

// Set request params
$params = array(
  "Contact" => $contact,
  "description" => "Barrel of Oil",
  "amount" => 500,
);

// Invoke WS method (Function1) with the request params 
$response = $client->__soapCall("Function1", array($params));

// Print WS response
var_dump($response);

?>

Testing the whole thing.

  • If you do print_r($params) you will see the following output, as your WS would expect:

Array ( [Contact] => Contact Object ( [id] => 100 [name] => John ) [description] => Barrel of Oil [amount] => 500 )

  • When I debugged the .NET sample WS I got the following:

enter image description here

(As you can see, Contact object is not null nor the other params. That means your request was successfully done from PHP side)

  • The response from the .NET sample WS was the expected one and this is what I got at PHP side:

object(stdClass)[3] public 'Function1Result' => string 'Detailed information of your request! id: 100, name: John, description: Barrel of Oil, amount: 500' (length=98)



You can use SOAP services this way too:

<?php 
//Create the client object
$soapclient = new SoapClient('http://www.webservicex.net/globalweather.asmx?WSDL');

//Use the functions of the client, the params of the function are in 
//the associative array
$params = array('CountryName' => 'Spain', 'CityName' => 'Alicante');
$response = $soapclient->getWeather($params);

var_dump($response);

// Get the Cities By Country
$param = array('CountryName' => 'Spain');
$response = $soapclient->getCitiesByCountry($param);

var_dump($response);

This is an example with a real service, and it works when the url is up.

Just in case the http://www.webservicex.net is down.

Here is another example using the example web service from W3C XML Web Services example, you can find more information on the link.

<?php
//Create the client object
$soapclient = new SoapClient('https://www.w3schools.com/xml/tempconvert.asmx?WSDL');

//Use the functions of the client, the params of the function are in
//the associative array
$params = array('Celsius' => '25');
$response = $soapclient->CelsiusToFahrenheit($params);

var_dump($response);

// Get the Celsius degrees from the Farenheit
$param = array('Fahrenheit' => '25');
$response = $soapclient->FahrenheitToCelsius($param);

var_dump($response);

This is working and returning the converted temperature values.


First initialize webservices:

$client = new SoapClient("http://example.com/webservices?wsdl");

Then set and pass the parameters:

$params = array (
    "arg0" => $contactid,
    "arg1" => $desc,
    "arg2" => $contactname
);

$response = $client->__soapCall('methodname', array($params));

Note that the method name is available in WSDL as operation name, e.g.:

<operation name="methodname">

I don't know why my web service has the same structure with you but it doesn't need Class for parameter, just is array.

For example: - My WSDL:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:ns="http://www.kiala.com/schemas/psws/1.0">
    <soapenv:Header/>
    <soapenv:Body>
        <ns:createOrder reference="260778">
            <identification>
                <sender>5390a7006cee11e0ae3e0800200c9a66</sender>
                <hash>831f8c1ad25e1dc89cf2d8f23d2af...fa85155f5c67627</hash>
                <originator>VITS-STAELENS</originator>
            </identification>
            <delivery>
                <from country="ES" node=””/>
                <to country="ES" node="0299"/>
            </delivery>
            <parcel>
                <description>Zoethout thee</description>
                <weight>0.100</weight>
                <orderNumber>10K24</orderNumber>
                <orderDate>2012-12-31</orderDate>
            </parcel>
            <receiver>
                <firstName>Gladys</firstName>
                <surname>Roldan de Moras</surname>
                <address>
                    <line1>Calle General Oraá 26</line1>
                    <line2>(4º izda)</line2>
                    <postalCode>28006</postalCode>
                    <city>Madrid</city>
                    <country>ES</country>
                </address>
                <email>[email protected]</email>
                <language>es</language>
            </receiver>
        </ns:createOrder>
    </soapenv:Body>
</soapenv:Envelope>

I var_dump:

var_dump($client->getFunctions());
var_dump($client->getTypes());

Here is result:

array
  0 => string 'OrderConfirmation createOrder(OrderRequest $createOrder)' (length=56)

array
  0 => string 'struct OrderRequest {
 Identification identification;
 Delivery delivery;
 Parcel parcel;
 Receiver receiver;
 string reference;
}' (length=130)
  1 => string 'struct Identification {
 string sender;
 string hash;
 string originator;
}' (length=75)
  2 => string 'struct Delivery {
 Node from;
 Node to;
}' (length=41)
  3 => string 'struct Node {
 string country;
 string node;
}' (length=46)
  4 => string 'struct Parcel {
 string description;
 decimal weight;
 string orderNumber;
 date orderDate;
}' (length=93)
  5 => string 'struct Receiver {
 string firstName;
 string surname;
 Address address;
 string email;
 string language;
}' (length=106)
  6 => string 'struct Address {
 string line1;
 string line2;
 string postalCode;
 string city;
 string country;
}' (length=99)
  7 => string 'struct OrderConfirmation {
 string trackingNumber;
 string reference;
}' (length=71)
  8 => string 'struct OrderServiceException {
 string code;
 OrderServiceException faultInfo;
 string message;
}' (length=97)

So in my code:

    $client  = new SoapClient('http://packandship-ws.kiala.com/psws/order?wsdl');

    $params = array(
        'reference' => $orderId,
        'identification' => array(
            'sender' => param('kiala', 'sender_id'),
            'hash' => hash('sha512', $orderId . param('kiala', 'sender_id') . param('kiala', 'password')),
            'originator' => null,
        ),
        'delivery' => array(
            'from' => array(
                'country' => 'es',
                'node' => '',
            ),
            'to' => array(
                'country' => 'es',
                'node' => '0299'
            ),
        ),
        'parcel' => array(
            'description' => 'Description',
            'weight' => 0.200,
            'orderNumber' => $orderId,
            'orderDate' => date('Y-m-d')
        ),
        'receiver' => array(
            'firstName' => 'Customer First Name',
            'surname' => 'Customer Sur Name',
            'address' => array(
                'line1' => 'Line 1 Adress',
                'line2' => 'Line 2 Adress',
                'postalCode' => 28006,
                'city' => 'Madrid',
                'country' => 'es',
                ),
            'email' => '[email protected]',
            'language' => 'es'
        )
    );
    $result = $client->createOrder($params);
    var_dump($result);

but it successfully!