Creating a Web Service with PHP 5

September 27th, 2007

This is part of my notes while trying to create a Web Service in PHP to be consumed by a SWF application written in ActionScript 2.0.
It is not intended to be the absolute truth, but a log of the things I've done to get it working.
First of all, I need to find out How to create a WebService with PHP 5

PHP 5 has a SOAP extension that lets you create web services in a few steps. You can even bind your service to a php class that you created.

PHP:
  1. <?php
  2. include("SenTe.php"); // This file has the php class that I want to use as a service.
  3. ini_set("soap.wsdl_cache_enabled", "0"); // disabling WSDL cache during development
  4. $server = new SoapServer("SenTe.wsdl"); // creates an instance of the SoapServer class (available in PHP5) and passes a reference to the WSDL file.
  5. $server->setClass("SenTe"); // Binds a class to be used as the service
  6. $data = file_get_contents('php://input'); // gets the contents of the post data (required in some PHP configurations)
  7. $server->handle($data); // and uses it when handling the service requests
  8. ?>

The WSDL problem

The only problem is that it does not provide a way to generate the WSDL file automatically. I found some workarounds to this problem. The best one being a PHP script that analyses your class and generates the WSDL XML file for you. The class was written by David Giffin and enhanced by Katy Coe. You can download the WSDL Writer class from Katy's website.

Testing the web service

We need a way to test the web service during development. After a google search I found soapIU. "soapUI is a free and open source desktop application for inspecting, invoking, developing, simulating/mocking and functional/load/compliance testing of web services over HTTP."

Specifying Data Types

My methods worked fine as long as they didn't return any values, or returned simple types, such as booleans, integers or strings. I soon realised that I was going to need to return arrays, and associative arrays (the latter being usually mapped to ActionScript Objects).

When I found how to generate the WSDL with the WSDL Writer class. I learned that the PHP code alone was not enough to define the data types, because PHP is a weakly typed languge. David Griffin's WSDL Writer works by parsing comments inmediately before the method declaration to determine the types of its arguments.

In the example below, the function install receives one integer and returns a boolean:

PHP:
  1. /**
  2. * @param int $foolproof FoolProof
  3. * @return boolean Success
  4. */
  5. function install($foolproof){
  6.   $rsp = false;
  7.   if($foolproof==1) $rsp = $this->game->install();
  8.   return $rsp;
  9. }

The WSDL Writer parses those comments and generates the proper WSDL description.

But what about arrays and associative arrays?
How do we specify those data types as return values? I found the answer on Katy's page.

Below is an example of how I specify an Array of Strings as the return data type. The function itself makes no sense. The input parameter $age is not being used. Don't worry:

PHP:
  1. /**
  2. * @param int $age Age
  3. * @return string[] Names
  4. */
  5. function getNames($age){
  6.   $rsp = Array("Sebastian","Fernando","Diego","Victor","Hernan","Alejandro");
  7.   return $rsp;
  8. }

Now what if I need to return an associative array? Something like:

PHP:
  1. function getUserDetails($id){
  2.   $rsp = Array("name"=>"Sebastian","age"=>31);
  3.   return $rsp;
  4. }

In order to return this kind of structures in my web service I need to specify a php class with the same structure somewhere in my PHP file.

PHP:
  1. class UserDetails{
  2.     /** @var string Users Name */
  3.     var $name;
  4.     /** @var int Users Age */
  5.     var $age;
  6.     function UsersDetails($n,$a){
  7.         $this->name = $n;
  8.         $this->age = $a;
  9.     }
  10. }

Then I can specify the data types on my method.

PHP:
  1. /**
  2. * @param int $id Age
  3. * @return UserDetails Details
  4. */
  5. function getUserDetails($id){
  6.   $rsp = new UserDetails("Sebastian",31);
  7.   return $rsp;
  8. }

By extension I can specify an Array of UserDetails simply by adding square brackets in the comments.

PHP:
  1. /**
  2. * @return UserDetails[] List of User Details
  3. */
  4. function getUsers(){
  5.   $rsp = Array();
  6.   $rsp[] = new UserDetails("Sebastian",31);
  7.   $rsp[] = new UserDetails("Victor",31);
  8.   $rsp[] = new UserDetails("Diego",32);
  9.   return $rsp;
  10. }

Handling SOAP Headers

This is a bit tricky. I just used this once, and I am still not sure of how it really works. However Katy describes it in her page.

Ok. This is it for now. I hope this helps me and others next time we need to create a web service.

2 Responses to “Creating a Web Service with PHP 5”

  1. Balu Says:

    Thanks a lot, that post saved my day (especially your description on arrays and pointing out Katy's script).

  2. Jeff Paul Scam Says:

    This post gave us a major Brainstorm session of all the possibilities we can utilize on our blog.

Leave a Reply