Few months ago, I blogged about How you represent custom headers in a WSDL. In there I mentioned, WSF/PHP is going to support sending and handling custom SOAP headers with the 2.0 release which was released early September. Today I will write how how to use this new feature in your Web Service Client.
In order to do the comparison I will show you how you could send Custom SOAP headers before WSF/PHP 2.0.
Preparing Custom SOAP Headers Manually
Before 2.0 you have to prepare the custom SOAP headers manually. For that you could use the WSHeader object.
Say you want to create the following message for your WSDL. (I excluded the headers and payload namespaces for the clarity)
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Header>
<Header1>
<string>test1</string>
<int>5</int>
</Header1>
<Header2>
<int>6</int>
<string>test2</string>
</Header2>
</soapenv:Header>
<soapenv:Body>
<echo>Hello</echo>
</soapenv:Body>
</soapenv:Envelope>
Here is how you prepare it using WSMessage and WSHeader objects.
// request payload
$requestPayloadString = <<<XML
<echo>Hello</echo>
XML;
// creation of two headers
$header1 = new WSHeader(array(
"name" => "Header1",
"data" => array(
new WSHeader(array("name" => "string",
"data" => "test1")),
new WSHeader(array("name" => "int",
"data" => "5")))));
$header2 = new WSHeader(array(
"name" => "Header2",
"data" => array(
new WSHeader(array("name" => "int",
"data" => "6")),
new WSHeader(array("name" => "string",
"data" => "test2")))));
// you prepare the soap message = request payload + two input headers
$request_msg = new WSMessage($requestPayloadString,
array("inputHeaders" => array($header1, $header2)));
// create the WSClient with the endpoint
$client = new WSClient(array( "to" => "http://localhost/header_echo_service.php" ));
// do the request with the WSMessage instance as the request argument
$responseMessage = $client->request($request_msg);
// print the response
printf("Response = %s <br>", htmlspecialchars($responseMessage->str));
As you can see you are preparing hierarchical tree of WSHeaders to prepare the SOAP message. Anyway after 2.0 you don’t need to write this much of code to get the work done.
Preparing Custom SOAP Headers in WSDL Mode
If you have a WSDL it is so easy to start by generating the initial code from the WSDL2PHP tool. If I take the WSDL from my old post about custom headers in WSDL WSDL2PHP tool will generate the following set of classes.
class Header1 {
/**
* @var string
*/
public $string;
/**
* @var int
*/
public $int;
}
class Header2 {
/**
* @var int
*/
public $int;
/**
* @var string
*/
public $string;
}
And you will get the following piece of code with the Note “TODO” where you need to fill the input fields and retrive the output values from the operation.
// create input object and set values
//TODO: fill $input with (data type: string) data to match your business logic
$header_in0 = new Header1();
// TODO: fill in the class fields of $header_in0 object which is of type Header1 to match your business logic
$header_in1 = new Header2();
// TODO: fill in the class fields of $header_in1 object which is of type Header2 to match your business logic
// call the operation
$response = $proxy->echoString($input, $header_in0, $header_in1, &$header_out0, &$header_out1);
//TODO: Implement business logic to consume $response, which is of type string
// TODO: Implement business logic to consume $header_out0 object, which is of type class Header1
// TODO: Implement business logic to consume $header_out1 object, which is of type class Header2
After I follow the guidelines in the comment, My code looks so simple and little like this,
// create input object and set values
$input = "Hello"; // I filled $input with a string
$header_in0 = new Header1(); // I m filling the header1
$header_in0->string = "test1";
$header_in0->int = 5;
$header_in1 = new Header2(); // now the header2;
$header_in1->string = "test2";
$header_in1->int = 6;
// call the operation
$response = $proxy->echoString($input, $header_in0, $header_in1, &$header_out0, &$header_out1);
// echoing the response payload which of type string
echo $response;
// echoing the $header_out0 object, which is of type class Header1
echo "output header0 contains {$header_out0->string} and {$header_out0->int}";
// echoing the $header_out1 object, which is of type class Header2
echo "output header1 contains {$header_out1->string} and {$header_out1->int}";
There the headers are PHP class objects. You fill the public variables of the classes and pass them to the ‘echoString’ operation. Although it looks like it call just a php function named ‘echoString’, it actually invoke the web service operation named ‘echoString’, with the request payload and custom SOAP headers. It returns the response payload value + the output headers to the references we passed as the last 2 arguments.
So with WSF/PHP 2.0 you can use WSDL mode and WSDL2PHP tool to send payload with custom headers with a little and quick code.