A PHP variable has a value and a type. In most practice cases we consider only about the value of the variable. But there may be times we have to consider the type of the variable as well.

For an example value NULL (or 0 or whatever of following you like  to call it) can be assigned to a variable with different types like this.

$x = NULL; NULL data type. Yea it is the real NULL.
$x = 0; Integer data type.
$x = 0.0; Float data type.
$x = FALSE; Boolean data type.
$x = “”; String data type.

You can check the operator ‘===’ (triple equal operator) to check equality of both their values and types simultaneously.

You can have a good idea about this by looking at the following piece of code.

// lets check the equality of NULL and 0 with
// double equal operator
if(NULL == 0) {
	echo "NULL == 0 is TRUE</br>";
}
else {
	echo "NULL == 0 is FALSE</br>";
}

// now lets check the equality of NULL and 0 with
// triple equal operator
if(NULL === 0) {
	echo "NULL === 0 is TRUE</br>";
}
else {
	echo "NULL === 0 is FALSE</br>";
}

This will eventually print the following result.

NULL == 0 is TRUE
NULL === 0 is FALSE

PHP variables including class variables get the NULL value and NULL type by default. So if no one assign them a value it remains NULL.

So in a case you have to check for unused variables (or for “NULL”-ness of a variable) you should always use the triple equal operator (===) with NULL token. Otherwise you may mistakenly treat not NULL things like ‘0′ or empty string (“”) as null that may have been valid data for your application.

Web Service can response with a Fault in 2 occasions.

  1. Fault send by the web service framework. (E.g. Invalid authentication, invalid signature found)
  2. Fault send by the user business logic.

There is a slightly difference in the content of SOAP 1.1 and SOAP 1.2. But they mainly contain the following elements.

  1. Code – A code to represent the classification of the fault. Possible fault codes can be found, http://www.w3.org/TR/soap12-part1/#faultcodes
  2. Reason – A human readable details of the reason.
  3. Details – More information about the details, mostly supposed to be read by the client application.
  4. Role – Indicates which SOAP header caused the fault. This is very rarely used in faults send from the business logic.

Sending SOAP Faults

In WSF/PHP you have the WSFault class to deal with SOAP faults. You can send a fault in your service logic by throwing an instance of WSFault class like this.

/**
 * divide mathematical operation
 * @param int $dividend
 * (maps to xs:int)
 * @param int $divisor
 * (maps to xs:int)
 * @return float $result
 * (maps to xs:float)
 */
function divide($dividend, $divisor)
{
	// dividing from 0 is invalid, we wil *throw* fault in such cases..
	if($divisor == 0) {
		throw new WSFault("Sender", "dividing from 0 is invalid");
	}

	$result = (float)$dividend/$divisor;

	return array("result" => $result);
}

Here I have throw an WSFault whenever I encounter my divisor is zero. And the WSF/PHP will take care of building the SOAP message according to the given version (default is to SOAP 1.2) and send back to the client.

Handling SOAP Faults

Similar to the service, client API also treat the SOAP fault as an instance of WSFault. So whenever you do a web service request, put inside try, catch block so you can catch exception in case of fault is received. Here is an example of handling fault while calling the divide operation in the above example.

// creating the client, we retrieved the wsdl from service url + ?wsdl
$client = new WSClient(array(
			"wsdl" => "http://localhost/myblog/fault_service.php?wsdl"));

$proxy = $client->getProxy();

try {
	// calling the operation
	$response = $proxy->divide(array("dividend" => 5, "divisor" => 0));

	// printing the result
	echo $response["result"];

} catch(Exception $e) {

	// if the instance is WSFault we print the code and the reason
	if ($e instanceof WSFault) {
        printf("Soap Fault Reason: %s\n", $e->Reason);
        printf("Soap Fault Code: %s \n", $e->Code);
	} else {
		printf("Message = %s\n",$e->getMessage());
	}
}

As you can see WSF/PHP covers the complexity of building and handling SOAP faults, Rather it gives you an API with the use of PHP Exception Construct that you already familiar with.

You can watch a Screencast on How to Consume a Web Service Using WSF/PHP from WSO2 Oxygent Tank developer portal.

There I have presented the steps you need to follow to consume a web service. I choose US National Digital Forecasting database Web Service as my example service to write the demo client.

This screencast contains,

  1. Where to find the Service documentation + WSDL and what are the information available in there.
  2. How to generate the PHP client from the WSDL using wsdlphp tool.
  3. What is in the php file generated from the wsdl2php tool and how you select the required operations to invoke.
  4. How to fill the input parameter for the web service operation
  5. How to handle the response returned from the service.
  6. Finally It shows some different ways the data that you are extracting from the service, can be presented to your user.

WSDL Caching is first introduced with the WSF/PHP 2.0.0 release to optimize the response time of PHP web services. In WSDL Caching WSF/PHP keeps an intermediate XML model which is generated from the WSDL in memory. This intermediate model which we call as ‘SIG’ or ‘Signature’ model is generated at the first request to the service. This SIG can be generated using an XSLT template from any WSDL 2.0. So if you provide a WSDL version 1.1, WSF/PHP first convert it to a WSDL 2.0 using another XSLT template and then generate the SIG model. So in generally when WSDL caching is used it avoids two XSLT parses and hence optimize the response time significantly.

In this blog, I will show you a result of some performance tests I did to measure the response time of a service with and without WSDL Caching.

The complete source codes used for the test can be found from here.

Here is a part of the service script I used. It is a simple echo service that echo a string.

	// create service in WSDL mode
	$service = new WSService(array ("wsdl" =>"echo.wsdl",
			"cacheWSDL" => false, // By default cache WSDL is true
			"actions" => $actions,
			"operations" => $operations));

	// getting the start_time
	$start_time = microtime(true);

	// process client requests and reply 
	$service->reply();

	// getting the end time
	$end_time = microtime(true);

	// getting the time difference
	$time_diff = $end_time - $start_time;

	logme($time_diff);

You can see in there I have set the “cacheWSDL” to false and log the time taken by the $service->reply() function. Later I have set the “cacheWSDL” to true and measure the time again for the comparison with earlier values.

I have written a client to invoke the service 10 times. And I’m going to measure the time taken do the client request in there.

	    for($i = 1; $i <= 10; $i ++) {
		// create client in WSDL mode
		$client = new WSClient(array ("wsdl" =>"echo.wsdl"));

		// get proxy object reference form client 
		$proxy = $client->getProxy();

		// create input object and set values
		//TODO: fill $input with (data type: string) data to match your business logic
		$input = "Hello World";

		// getting the start_time
		$start_time = microtime(true);

		// call the operation
		$response = $proxy->myEcho($input);
		//TODO: Implement business logic to consume $response, which is of type string

		// getting the end time
		$end_time = microtime(true);

		// getting the time difference
		$time_diff = $end_time - $start_time;

		logme($time_diff);

		echo $response."</br>";

	    }

Then I have measured the time taken to first 10 request for both WSDL caching on and off scenarios just after starting the Apache server.

Without WSDL Caching With WSDL Caching
WSClient Operation invocation
$client->myEcho($input)
WSService reply
$service->reply()
WSClient Operation invocation
$client->myEcho($input)
WSService reply
$service->reply()
0.11091995239258 0.074313163757324 0.15158987045288 0.11872982978821
0.082005977630615 0.06772780418396 0.046205997467041 0.035470008850098
0.082638025283813 0.072394132614136 0.044647932052612 0.028353929519653
0.079883098602295 0.06883692741394 0.037378072738647 0.026839017868042
0.082012176513672 0.068314790725708 0.046517133712769 0.035148859024048
0.074619054794312 0.063674211502075 0.041852951049805 0.027253866195679
0.084127187728882 0.071602821350098 0.041593074798584 0.027820825576782
0.081571102142334 0.066971063613892 0.057910919189453 0.038385152816772
0.087567090988159 0.073211193084717 0.043420076370239 0.02738094329834
0.078658103942871 0.064589977264404 0.050504922866821 0.037022113800049

If you obvious these values you will figure out when you don’t use WSDL caching it takes same amount of time to server each request. But when you turn on WSDL caching it takes a little more time at the very first request, but the subsequent requests take very low values.

Here is the chart for the above Data, See the Green and White lines corresponding to the WSDL caching turn on, have taken low values. In average we can observe a 50% reduction in server response time with the WSDL caching.

Response Time With and Without WSDL Caching

Response Time With and Without WSDL Caching

This result is for a very simple WSDL which only had an echo operation. When the WSDL get more complex and contain lot of wsdl/schema includes and imports, we can expect more optimization due to the WSDL caching. We will check how the complexity of the WSDL affect the performance in a later blog post.:)

In XML Schema we declare an array or a multiple occurrence of a schema element by setting its maxOccurs attribute to a value greater than 1 or to the value “unbounded” in a case of no maximum boundary.

<xs:element maxOccurs="unbounded"
            minOccurs="0"
            name="params"
            nillable="true"
            type="xs:int"/>

If you generate PHP code to such a schema using wsdl2php tool, you will get a code for the class variable named “params” similar to this.

    /**
     * @var array[0, unbounded] of int
     */
    public $params;

So if you have a variable (say $object) for the object of this class you can fill the “params” field like this,

$object->params = array(1, 5, 8);

This will create the xml with the expected array of elements.

<wrapper>
    <params>1</params>
    <params>5</params>
    <params>8</params>
</wrapper>

Not only for simple types, you can have arrays of complex types too.

<xs:element maxOccurs="unbounded"
            minOccurs="0"
            name="params"
            nillable="true"
            type="tns:MyComplexType"/>

Instead of giving simple integers like earlier case, this time you will feed the “params” variable with an array of PHP objects of ‘MyComplexType’ class.

$obj1 = new MyComplexType();
/* feeding data to obj1 variables */

$obj2 = new MyComplexType();
/* feeding data to obj2 variables */

$obj3 = new MyComplexType();
/* feeding data to obj3 variables */

$object->params = array($obj1, $obj2, $obj3);

This will create a xml containing array of params similar to this,

<wrapper>
    <params>
        <elementx/> <!-- elements in the MyComplexType type -->
        <elementy/>
    </params>
    <params>
        ... <!-- elements in the MyComplexType type -->
    </params>
    <params>
        ... <!-- elements in the MyComplexType type -->
    </params>
</wrapper>

PHP2WSDL feature of the WSF/PHP allows you to generate the WSDL for your service when you access the URL formed by adding “?wsdl” to the service URL ( or you can use service URL + “?wsdl2″ to access the wsdl version 2.0). It will generate the schema types for the wsdl from the classes you use to build the request message + the annotations you provided describing the types of the variables.

Sometime you may need to generate schema types with different names to the corresponding PHP classes. May be you need to have a ‘-’ in the schema type which is not valid in PHP class syntax or you like to have a different naming convention for PHP and wsdl.  Similarly you may need to have the operation names different in the WSDL and the PHP code.

Here is how you do it with WSF/PHP.

Different Names for Operations

/**
 * Service logic for the echo operation
 * @namespace http://ws.dimuthu.org/php/myecho/operations
 * @param object testObject $param
 * @return object testObject $return
 */
function echoMe($param) {
  return $param;
}

/* The Service operation name to PHP function name map */
$operations = array("echo" => "echoMe");

There I want my actual operation name to be echo. But I can’t declare a function name echo since PHP already has a library function echo (Yea, the one you regularly use to echo output). So I don’t have option other than declaring a function with different name (here it is “echoMe”) and mapped it in to echo operation in the operation map. We are going to feed this $operation variable at the WSService creation as its constructor argument.

Lets see how different names are used in schema types and corresponding php class names.

Different names for Types and Classes

/**
 * @namespace http://ws.dimuthu.org/php/myecho/types
 */
class testObject {

	/**
	 * @var integer aint
	 */
	public $aint;

	/**
	 * @var string astring
	 */
	public $astring;
}

/* The mapping of schema types to PHP class */
$classmap = array("test-object" => "testObject");

It is similar how we mapped operation in the previous section. Just use $classmap variable which map the schema type name to the php class name.

Here is the type section and the interface section of the WSDL 2.0 generated using above codes. Observe the operation names and the types names are formed the way we expected.

  <types>
    <xsd:schema xmlns:ns0="http://ws.dimuthu.org/php/myecho/types"
        xmlns:ns1="http://ws.dimuthu.org/php/myecho/types"
        elementFormDefault="qualified"
        targetNamespace="http://ws.dimuthu.org/php/myecho/operations/xsd">
      <xsd:import namespace="http://ws.dimuthu.org/php/myecho/types"/>
      <xsd:element name="param" type="ns0:test-object"/>
      <xsd:element name="return" type="ns1:test-object"/>
    </xsd:schema>
    <xsd:schema elementFormDefault="qualified"
                targetNamespace="http://ws.dimuthu.org/php/myecho/types">
      <xsd:complexType name="test-object">
        <xsd:sequence>
          <xsd:element name="aint" type="xsd:integer"/>
          <xsd:element name="astring" type="xsd:string"/>
        </xsd:sequence>
      </xsd:complexType>
    </xsd:schema>
  </types>
  <interface name="myEchoPortType">
    <operation name="echo" pattern="http://www.w3.org/ns/wsdl/in-out">
      <input element="tnx:param"/>
      <output element="tnx:return"/>
    </operation>
  </interface>

Here is the complete code (Combining all the previously mentioned code segments). You can check the complete wsdl generation (wsdl  1.1 or wsdl 2.0 as your preference) by copying and pasting this code to the online php2wsdl generator at the WSF/PHP Demo Site.

<?php

/**
 * Service logic for the echo operation
 * @namespace http://ws.dimuthu.org/php/myecho/operations
 * @param object testObject $param
 * @return object testObject $return
 */
function echoMe($param) {
  return $param;
}

/**
 * @namespace http://ws.dimuthu.org/php/myecho/types
 */
class testObject {

	/**
	 * @var integer aint
	 */
	public $aint;

	/**
	 * @var string astring
	 */
	public $astring;
}

/* The Service operation name to PHP function name map */
$operations = array("echo" => "echoMe");

/* Telling that we input MIX types for the parameters */
$opParams = array("echo" => "MIXED");

/* The mapping of schema types to PHP class */
$classmap = array("test-object" => "testObject");

/* Creating the WSService and serving the Request */
$service = new WSService(array(
			"operations" => $operations,
			"classmap" => $classmap,
			"opParams" => $opParams,
			"serviceName" => "myEcho"));

$service->reply();

?>

Samisa Abeysinghe who is the director of engineering at WSO2 and one of the key leaders of the WSF/PHP project has published a book titled RESTful PHP Web Services.

RESTful PHP Web Services - Samisa Abeysinghe

RESTful PHP Web Services - Samisa Abeysinghe

In Samisa’s Blog He describes the structure and the content of the book in his own words.

If you are developing RESTful web services in PHP, you will find this book will be a great reference.

If you are thinking of writing a web service or a client based on a WSDL, you can easily generate the code for PHP or any other language using tools likes wsdl2php or other wsdl2xxx category tools. Then you don’t need to really worry about what is the schema of the WSDL or any other finer details. But sometime it may useful to know how different schema constructs are generated in PHP level so you can have a good idea when you are using them. This post describes How inheritance is used in XML Schema and how it is mapped to PHP code from wsdl2php tool in WSF/PHP.

There are several ways that one schema type can inherit another type.  Here are some names use to refer them.

  • SimpleType Restriction – Forming simple type by restricting another simple type
  • SimpleContent Extension – Forming complex type by extending a simple type
  • ComplexContent Extension – Forming complex type by extending another complex type

Note that here the word ‘type’ always refers to a schema type.

It is not straight forward to do a one to one map from these schema structures to a PHP or some other language. But wsdl2php tool does that keeping the simplicity and preserving the original meaning. Lets see how it is done for each of the above mentioned methods of inheriting.

SimpleType Restriction

You can create a simple type by restricting some values of another simple type. Here is an example.

            <!-- derivedType from applying
              simple type restriction for xs:string -->
            <xs:simpleType name="derivedType">
                <xs:restriction base="xs:string">
                    <xs:enumeration value="a"/>
                    <xs:enumeration value="ab"/>
                    <xs:enumeration value="abc"/>
                    <xs:enumeration value="abcd"/>
                </xs:restriction>
            </xs:simpleType>

Here the derivedType is a string, but it can only have values “a”, “ab”, “abc” and “abcd”. This restriction have used the “enumeration” (which we call a facet) to restrict the possible values. You can use other facets like length, minLength, MaxLength and so on. Here are the complete list of facets in the schema specification.

So lets see hows this is mapped to a PHP code. Here we assume this type is used in an schema element called ‘input’.

    /**
     * @var string
     *     NOTE: $input should follow the following restrictions
     *     You can have one of the following value
     *     a
     *     ab
     *     abc
     *     abcd
     */
     public $input;

Note that here it does not say anything about the ‘derivedType’. Rather it says it is of type “String” which is a PHP type and in addition it has some restrictions, or rules when assigning values.

Although it could have been possible to use getters and setters to impose these rules, this uses just a comment about the rules because this way it is really easy the use the variable.

Say we have another type (say derievedType2) restricting the ‘derievedType’, that type will have the combination of restrictions of both types.

Here is the xml schema representation of the ‘derievedType2′.

            <!-- derivedType2-->
            <xs:simpleType name="derivedType2">
                <xs:restriction base="tns:derivedType">
                    <xs:maxLength value="3"/>
                    <xs:minLength value="2"/>
                </xs:restriction>
            </xs:simpleType>

And if input2 have that type, the php code will look like this, (Note that it has the combination of rules).

    /**
     * @var string
     *     NOTE: $input2 should follow the following restrictions
     *     You can have one of the following value
     *     a
     *     ab
     *     abc
     *     abcd
     *     Your length of the value should be
     *     Greater than 2
     *     Less than 3
     */
     public $input2;

I have highlighted the additional rules compared with $input, so you can see the difference.

SimpleContent Extension

Simple Content extension is extending a simple type to make a complex type. Say we have an element (say with the name “mystring”) and it has “xs:string” simple type.

<xs:element name="mystring" type="xs:string"/>

And here is a valid xml with this schema.

<mystring>this can contain only string</mystring>

So if I say I’m going to make a complex type extending this simple type you may think that I’m going to add element in to that. In fact I will create a complex type by adding an attribute.

<mystring myint="3">this can contain only string</mystring>

The schema to this xml will be something like this. (Note that I have assumed there is an schema element named “mystring” with the type “myStringType”)

            <xs:complexType name="myStringType">
                <xs:simpleContent>
                    <xs:extension base="xs:string">
                        <xs:attribute name="myint" type="xs:int"/>
                    </xs:extension>
                </xs:simpleContent>
            </xs:complexType>

The PHP generated code for this schema is something like this,

class myStringType {

    /**
     * @var int
     */
    public $myint;

    // The "value" represents the element 'myStringType' value..

    /**
     * @var string
     */
    public $value;

}

So as you can see it creates a PHP class for that schema type with member variables for each attributes and finally for the value of the parent type. So in order to represent the above mentioned xml, you will use the following PHP code.

$type = new myStringType();

$type->myint = 3;
$type->value = "this can contain only string";

Next we will look at the inheritance with complexContent Extension.

ComplexContent Extension

This is to create a complex type by inheriting another complexType.

            <!-- the parent type -->
            <xs:complexType name="parentType">
                <xs:sequence>
                    <xs:element name="demo3" type="xs:int"/>
                    <xs:element name="demo4" type="xs:string"/>
                </xs:sequence>
            </xs:complexType>

            <!-- the child type -->
            <xs:complexType name="childType">
                <xs:complexContent>
                    <xs:extension base="tns:parentType">
                        <xs:sequence>
                            <xs:element name="demo1" type="xs:int"/>
                            <xs:element name="demo2" type="xs:string"/>
                        </xs:sequence>
                    </xs:extension>
                </xs:complexContent>
            </xs:complexType>

So here the childType will inherit the ‘demo3′ and ‘demo4′ elements from the parent type. We will see how is the PHP generated code looks like.

class parentType {

    /**
     * @var int
     */
    public $demo3;

    /**
     * @var string
     */
    public $demo4;

}

class childType extends parentType {

    /**
     * @var int
     */
    public $demo1;

    /**
     * @var string
     */
    public $demo2;

}

It has uses the PHP inheritance to reprensent the schema inheritance. And the nice thing is you can use the childType for the places you have to use the parentType.  That is the theoy we learn at the inheritance class of other languages (Java, C++) too.

So say there is another complexType (say “anotherChildType”) inheriting from the type “parentType” and one another complexType (say “nextLevelChildType”) inheriting this time from “childType” (which in fact inheriting from the “parentType” as mentioned above).

So our types tree would be something like this.

--- parentType
         |
         +-------- childType
         |              |
         |              +------------- nexLevelChildType
         |
         +-------- anotherChildType

And lets say there is a schema element called ‘input3′ with the type parentType. Then the generated variable for the input3 element will be like following code segment.

    /**
     * @var (object)parentType
     *    Or one of following derived class(es)
     *       childType
     *       nextLevelChildType
     *       anotherChildType
     */
    public $input3;

This comment tells you that you can actually use the inherited types in place of the parent type according to your preferences.

WSF/PHP Demo Site contains number of sample web service applications which demonstrate the different features of WSF/PHP. From these demos, Mashup Search Demo demonstrate  the use of  publicly available web services to create a search mashup in your web site.

This demo consists of 3 public web services namely Flickr, Yahoo and Amazon.

Flickr Yahoo Amazon
Service Documentation Page Flickr API Docs
Yahoo API Docs
Amazon API Docs
REST/SOAP REST REST SOAP and REST
Registration for Key Flickr API registration
Yahoo API registration
Amazon API Registration
Source code for sample consumer Flickr Demo Source
Yahoo Demo Source
Amazon Demo Source
PHP class used FlickrClient YahooClient AmazonClient
Available Operations
  • photosTextSearch
  • photosTagSearch
  • webSearch
  • newsSearch
  • imageSearch
  • localSearch
  • itemSearch
  • itemLookup

October 18th, 2008Write RESTful Services in C

You can write REST as well as SOAP web services using Apache Axis2/C web services framework. There you can make existing Axis2/C web services RESTful just by providing the URL patterns and the HTTP methods to each operation in  the services.xml which act as a simple descriptor for an Axis2/C service.

So if we rewrite the RESTful Demo (Written in PHP) using Axis2/C, the services.xml would be something like following.

<service name="RESTfulSchool">
    <!-- mentioning the service library-->
    <parameter name="ServiceClass" locked="xsd:false">RESTfulSchool</parameter>

    <!-- some description -->
    <description>
        The RESTful School demo
    </description>

    <!-- list of operations -->
    <operation name="getSubjects">
            <parameter name="RESTMethod">GET</parameter>
            <parameter name="RESTLocation">subjects</parameter>
    </operation>
    <operation name="getSubjectInfoPerName">
            <parameter name="RESTMethod">GET</parameter>
            <parameter name="RESTLocation">subjects/{name}</parameter>
    </operation>
    <operation name="getStudents">
            <parameter name="RESTMethod">GET</parameter>
            <parameter name="RESTLocation">students</parameter>
    </operation>
    <operation name="getStudentInfoPerName">
            <parameter name="RESTMethod">GET</parameter>
            <parameter name="RESTLocation">students/{name}</parameter>
    </operation>
    <operation name="getMarksPerSubjectPerStudent">
            <parameter name="RESTMethod">GET</parameter>
            <parameter name="RESTLocation">students/{student}/marks/{subject}</parameter>
    </operation>
</service>

We will check how to write the service logic for a operation like “getMarksPerSubjectPerStudent”.

axiom_node_t *
RESTfulSchool_getMarksPerSubjectPerStudent(
    const axutil_env_t * env,
    axiom_node_t * request_payload)
{
    axiom_node_t *student_node = NULL;
    axiom_node_t *subject_node = NULL;

    /* Extracting out the child nodes from the request */
    student_node = axiom_node_get_first_child(request_payload, env);
    subject_node = axiom_node_get_next_sibling(student_node, env);

    /* now we can write the logic to retrieve the marks
       for the given student and subject and build and
       return the response payload */

    return response_payload;
}

As you can see the variables {student} and {subject} given in the services.xml can be easily accessed from your business logic, so we can build the response accordingly.

This way you can build a RESTful web services easily using C language.


© 2007 Dimuthu’s Blog | iKon Wordpress Theme by Windows Vista Administration | Powered by Wordpress