Build a Web service with PHP

Learn how to create integrated Web applications with SOAP


Before you start

About this tutorial

This tutorial is for PHP programmers that would like to jump on the Web services bandwagon by creating a Web service in PHP. You'll build a Web service by building a SOAP server in PHP. The Web service you will create will be a vehicle lookup service that takes in queries based on make, model, and year. The Web service will then query an internal database and respond appropriately. A Web-based client will also be coded in PHP to communicate and query the SOAP server. It creates a chain of three SOAP servers in PHP. In reality, each of the three servers would be placed in three different physical locations or cities where a chain of car dealerships would coexist. The client would then be hosted at one location where car customers would come and visit, entering search queries to find the vehicles of their dreams. The client routes the query to each of the three SOAP servers, which, in turn, send results back to the client. Upon receiving each response, the client displays the search results to the user for analysis.

System requirements

The following tools are needed to follow along:

Web server
Any operating system and any Web server can be used. Feel free to use Apache V2.X, or IBM's HTTP Server; download from Apache or from IBM.
Due to the use of PHP data objects, PHP V5.1 or later is required. Be sure to configure with the following option to include support for Derby and the SOAP extensions: --with-pdo-odbc=ibm-db2,/home/db2inst1/sqllib --enable-soap. See Related topics for information about configuring Apache or IBM's HTTP Server with PHP.
This tutorial uses Apache Derby, which is open source and lightweight. Also download the IBM DB2® JDBC Universal Driver and the DB2 Run-Time Client. Make sure to set your CLASSPATH appropriately by following the instructions on each page. You can follow the Linux® or Windows® instructions for installing and downloading the DB2 Run-Time Client. See Related topics for more information to help you get the configuration right.

IBM Cloudscape may also be used for this tutorial. The internals of it are the same as Derby; however, the DB2 JDBC Universal Driver and other things are packaged into Cloudscape, and it is supported by IBM. Download IBM Cloudscape V10.1 and the DB2 Run-Time Client from IBM.
Java technology
Derby requires Java™ technology. Download from Sun Microsystems or from IBM.

Overview and setting up

Web services have been a hit for some time now, and the popularity just keeps growing. But why? It's because they are the perfect way to integrate several entities into one, allowing for better flow of information to management and to customers.

PHP is definitely not behind in this area. Being one of the fastest-growing languages, PHP commands a host of developers that require this technology, too. Take a look at the technology behind Web services, SOAP, and how databases like Derby help enable a more powerful Web service.


What does SOAP mean? It stands for Simple Object Access Protocol, and it's essentially a standard for exchanging XML-based data via HTTP. In other words: It's the signal that goes down the telephone lines if you were talking with your friend on the phone, but instead of you and your friend talking on the phone, it'll be car customers searching for the vehicles of their dreams in a chain of car dealerships. An example of a SOAP message is shown in Listing 1.

Listing 1. A SOAP message
      <faultstring>Bad Request. Can't find

While you'll see this again later, it's shown here so you can get a feel for the technology. The body of most SOAP messages has data, similar to the fault shown here. Sometimes a header is used to hold encryption and other context-sensitive data for the SOAP construct being sent. Also, SOAP messages are sent as raw XML data.

How databases fit in

A Web service can hardly be useful without a database. You can use a database to store information about what a particular user queried or looked at during a visit. Most existing systems of large companies have a vast array of databases and information, making the use of databases vital for a successful Web service -- even for established Web sites.

Site information is almost always stored in a database, and accessing such information via a Web service is just as important. So learning how to integrate your PHP Web service with a database is vital, just as it is with the basic PHP setup. PHP development just isn't PHP development without a database ready at your beck and call.

The example dealership application in PHP

In this tutorial, you'll take advantage of all the above for your Web service, enabling you to get a jumpstart into your own PHP Web service development. The application you're going to build has a user interface where users can enter queries, as shown below.

Figure 1. Searching for the vehicle of your dreams
Searching for the vehicle of your dreams
Searching for the vehicle of your dreams

Simple SOAP server in PHP

You'll create a simple SOAP server to learn to use basic PHP SOAP server capabilities. This section will give you a taste of and prepare you for the rest of the tutorial.

Creating a server

A simple server takes a SOAP request and returns a response. Create a simple echo application that takes in a string and sends it back with the word ECHO tacked onto the front. Create a file called simple_server.php, and define it as shown below.

Listing 2. A simple SOAP server

function echoo($echo){
    return "ECHO: ".$echo;

$server = new SoapServer(null,
                         array('uri' => "urn://tyler/res"));


The first item is the echoo function. It returns the string passed to it and appends ECHO: to the front of it. Also, see how the SoapServer object is created in PHP. Then add the echoo function to the list of functions that the SOAP server supports. You have to call the function echoo because echo is a reserved word in PHP, similar to the print command. The last line calls the handle method of the SoapServer object, allowing the server to handle the SOAP request and return a response, as defined in the echoo method.

SOAP messages

Pointing a browser to your SOAP server in its current status causes a fault because of the way the request is sent. The data needs to be sent as raw POST data via HTTP, as described by the faultstring.

Listing 3. Pointing a browser to the SOAP server
      <faultstring>Bad Request. Can't find

Your server is now live, but you can only access it via a SOAP client or you'll get fault errors, as shown above. Now that you know the SOAP server is working, you can move onto creating a simple client.

Creating a client: Echo form

A client allows you to send data to the SOAP server using the correct expected protocol. Since all you need is any string to send to the SOAP server to test it out, you'll create a simple form with one text box and a button. Create a file called simple_client.php and define it, as shown below.

Listing 4. Creating a simple form

$echo = $_GET['input'];

print "<h2>Echo Web Service</h2>";
print "<form action='simple_client.php' method='GET'/>";
print "<input name='input' value='$echo'/><br/>";
print "<input type='Submit' name='submit' value='GO'/>";
print "</form>";

Because of the function of the application, the method by which you'll send requests to the SOAP server will be via GET. If the function had side-effects, like database modification or logging in, you'd want to use POST.

The code first retrieves the value of input from the GET array or URL. Next, the form is created, with the action field being this same PHP script, simple_client.php, so GET requests from this form get sent to this same PHP script. Notice that there are two input tags: the text box where you'll type the value to have returned from the SOAP server and the GO button. A preview of the form is shown below.

Figure 2. The Echo form
The Echo form
The Echo form

Creating a client: Making the request

Once the button is clicked, the text in the text box, shown above, gets sent to the PHP script in the URL, which you can extract in the GET array. This allows you to verify that a request was sent and process it. Continue defining the simple_client.php file, as shown below.

Listing 5. Handling requests and sending them to the SOAP server
print "</form>";

if($echo != ''){
    $client = new SoapClient(null, array(
      'location' => "http://localhost/soap/simple_server.php",
      'uri'      => "urn://tyler/req"));

    $result = $client->

    print $result;

Now if $echo has data in it, something was entered in the text box, and a request was made. This allows you to initiate the request to the SOAP server by creating the SoapClient object. The client knows where to send requests by the location in the parameters array. The uri gives the SOAP packet a namespace, which is essentially a context. Once the SoapClient is initialized, make the request to the SOAP server by calling the client's __soapCall method with two parameters: the method in the SOAP server you wish to call and an array of parameters. Then you display the response sent from the SOAP server underneath the GO button, which you can preview below.

Figure 3. Displaying the response from the SOAP server
Displaying the response from the SOAP server
Displaying the response from the SOAP server

There you have it. You can even see the value of the input text box in the URL. Now that you've created a simple SOAP server, you'll create a more complex one that uses Apache Derby and multiple SOAP servers.

Derby: Setting up

Derby's a great database for this application because it's lightweight and easy to use. The application in this tutorial uses it to search for vehicles matching the search criteria, and this section sets everything up, so you're good to go.

Creating the database

Since PHP connects to Derby using the network server and ODBC, start the server by typing:

java org.apache.derby.drda.NetworkServerControl start

When the application starts, it's ready to accept connections. Connect to and create a new database using the Derby ij tool:


You should now be at the ij prompt, where you can enter database commands. The ij tool allows you to create and connect to databases, as well as query them as you would in PHP. This helps you fine-tune and perfect your search queries before implementing them in your PHP application. Now you'll create and connect to the database:


Here, you've created the DEALER database with user and password being dealer. Next, you'll catalog the database in DB2 so the PHP ODBC drivers will see our new database and be able to connect to it.

Cataloging the database in DB2

Start the DB2 client: In Linux, type db2 at the command line; in Windows, click on the Command Line Processor application installed under Programs > IBM DB2 > Command Line Tools. When you have the DB2 prompt up, type the following:

catalog tcpip node cns remote localhost server 1527

This creates a node you'll catalog the database to:

catalog db DEALER at node cns authentication server

Our DEALER database is now associated with the cns node. Next, catalog the DEALER database as a system ODBC data source so the PHP ODBC drivers will find and recognize the DEALER database:

catalog system odbc data source DEALER

The DEALER database is ready to go! You could connect to it in PHP, but before you do, learn more about its purpose and initialize it with tables.

The DEALER database

This database holds three tables -- one for each physical dealership location. Each location will have its own table in the database with vehicle data. And when queries from the SOAP client come to the SOAP server, each SOAP server will query its own database table and return the results for it. The three tables:

  • vehicles_steinbach
  • vehicles_pinefalls
  • vehicles_selkirk

Each table contains the vehicles for each of three cities, which you'll create next.

Creating the vehicle tables for each location

Create each of the three tables for the dealership application using the ij tool. Create them using the SQL commands at the ij prompt, as shown below.

Listing 6. Create the three tables
drop table vehicles_steinbach;
create table vehicles_steinbach (make varchar(50),
                                 model varchar(50),
                                 yyear varchar(4),
                                 price integer,
                                 feature_desc varchar(512));

drop table vehicles_pinefalls;
create table vehicles_pinefalls (make varchar(50),
                                 model varchar(50),
                                 yyear varchar(4),
                                 price integer,
                                 feature_desc varchar(512));

drop table vehicles_selkirk;
create table vehicles_selkirk   (make varchar(50),
                                 model varchar(50),
                                 yyear varchar(4),
                                 price integer,
                                 feature_desc varchar(512));

Each table has a make, model, yyear, price, and feature_desc describing a vehicle's features.

The database skeleton is complete with the creation of these tables. Now let's fill in the guts by adding some content to the database.

Initializing each table with vehicle information

Most dealerships -- even chains -- customize each dealership to a certain make, etc. You'll see this in the choices for the contents of each table. Use the following SQL, shown below, or create content of your own as the content of the database.

Listing 7. Filling in the three tables with content
insert into vehicles_steinbach values
('Chrysler', 'Crossfire', '2005', 19999,
                          'Air conditioning, power windows'),
('Chrysler', 'Sebring',   '2003', 14999, 'Convertible'),
('Dodge',    'Viper',     '2006', 89999, 'loaded'),
('Chrysler', '300',       '2003', 18999, 'Leather seats'),
('Dodge',    'Durango',   '2004', 23999, 'Supercharged engine');

insert into vehicles_pinefalls values
('Toyota', 'Camry',  '2001', 13999, 'Power steering'),
('Toyota', 'Tacoma', '2002', 16999, 'Power seats'),
('Lexus',  'LS',     '2003', 26999, 'Built in GPS'),
('Toyota', 'Prius',  '2004', 29999, 'Built in TV and DVD player'),
('Lexus',  'GS',     '2005', 34999, '10 CD changer');

insert into vehicles_selkirk   values
('Saturn', 'Vue',   '2004', 15999, 'Power locks'),
('Saturn', 'Ion',   '2005', 12499, 'Reliable'),
('Saturn', 'Sky',   '2006', 19999, 'Convertible, must see!'),
('Saturn', 'Relay', '2004', 14999, 'Very roomy'),
('Saturn', 'L300',  '2001',  9999, 'Chrome wheels');

Your database is finished and ready to be queried by your PHP application, which you'll begin architecting next.

Architecting the user interface

With the database ready to go, you can begin work on the PHP application. By the end of this section, your application will have a user interface complete with a form that takes in the make, model, and year of the vehicle being searched for.

The header

When a page is requested, the header appears at the top of the page, and placing those contents in a separate PHP script makes your code modular and easier to read because you can simply include the header file at the top of a new script without it cluttering the file. Create a header.php file and define it, as shown below.

Listing 8. Creating a header file

define(COMPANY_NAME, 'SOAP Serverz R Us');

<table width="650px" align="center" valign="top">
<tr><td colspan="2">

<tr><td colspan="2">
<center><h1>Welcome to '.COMPANY_NAME.'</h1></center></td></tr>');

print('<tr><td height="100%">

This sets up the HTML for the page, as well as a structure defined by the <table ...> tag and displays a greeting to visiting users. It ends by opening up a <td ...> tag.

The footer

The concept of a footer file is similar to the concept of a header file. With the header and footer file together, you essentially no longer have to write basic HTML tags (like <html><body>) ever again. This allows you to focus on what you do best: PHP development. Create a file called footer.php and define it, as shown below.

Listing 9. Creating a footer file
<tr><td align="center" colspan="2">
<font size="2px"><br>
<center>Copyright 2006, <?php print(COMPANY_NAME) ?></center>

This file closes off the <td ...> and <table ...> tags from the header, and displays a little copyright saying you don't want your information copied. A preview of the current application, as shown in a browser, can be previewed in Figure 4.

Figure 4. The application with a header and footer
The application with a header and footer
The application with a header and footer

Looking up vehicles with a form

With the header and footer created, you can focus on the main content of the user interface for your application. Create a file called index.php and define it, as shown below.

Listing 10. Creating the form used to search for vehicles

$make = $_GET['make'];
$model = $_GET['model'];
$year = $_GET['year'];
print "<h3>Search for vehicles based on year, make or model:</h3>";
print "<table>";
print "<form action='index.php' method='GET'>;";
print "<tr><td>Make:</td><td>";
print "<input name='make' value='$make'/>;</td></tr>";
print "<tr><td>Model:</td><td>";
print "<input name='model' value='$model'/>;</td></tr>";
print "<tr><td>Year:</td>";
print "<td><input name='year' value='$year'/>;</td></tr>";
print "<tr><td><input type='submit' name='submit' value='GO'/>;";
print "</td></tr>";
print "</form>;";
print "</table>";

See how nice and compact the file is, without the clutter of the content currently in the header and footer files? Then you place the content of the page in the middle with a consistent layout.

The form consists of three text input boxes: one each for make, model, and year. The code for the form is in bold to make it easier for you to isolate, since you can format the rest however you want. Like the Echo form, the HTTP transfer method of this form is via GET because there will be no database or other side-effects caused by executing this query. Once the query is executing, the action field specifies that the form should send the data to this same index.php script. The first three lines of the script retrieve the data from the URL or GET array, which you'll process next. Before you go there, however, you can preview the form.

Figure 5. Searching for vehicles
Searching for vehicles
Searching for vehicles

Processing the form and calling the client

Once a request has been made by a car customer, your code needs to handle that request and call client code to request responses from each of the three SOAP servers. Do so by completing the index.php file, as shown below.

Listing 11. Handling requests from the user interface
print "</form>";
print "</table>";

if($_GET['submit'] === 'GO' &&
   ($make != '' || $model != '' || $year != '')){
    print "<h3>Search Results:</h3>";


You'll know that the request has been made by a car customer if the GET array's submit value equals GO. Now if the button got clicked and any one or more of the text boxes was filled in, initialize a request to the SOAP servers via the client code, which you'll define in the next section.

Now you'll create a simple Web server for each of the three locations, in preparation to test the client code you'll develop in the next section.

Simple Web services for each location

Start with a simplified version of the Web service and build on it later. Create three files: server_steinbach.php, server_pinefalls.php, and server_selkirk.php, and define each of them, as shown below.

Listing 12. Creating the three SOAP servers

function vehicleLookup($make, $model, $year){
    return '<tr><td>'.$make.' '.$model.' '.$year.'</td></tr>';

$server = new SoapServer(null,
                         array('uri' => "urn://tyler/res"));


Notice that the vehicleLookup method is what the client code will call in passing the vehicle search query to the SOAP servers.

Great! Your application framework is ready for the client code.

The client

Client code is usually referred to as code that creates a client capable of communicating with a server, sends a request, and receives a response. That's what you'll develop in this section: code that creates clients to communicate with each of the three dealership locations.

Initializing a client for each location

The first step in sending requests to the SOAP servers is creating three clients with their locations set to point to each of the three URLs of the three SOAP servers. Create a file called client.php and define it, as shown below.

Listing 13. Create three SOAP clients

$client_steinbach = new SoapClient(null, array(
      'location' => "http://localhost/soap/server_steinbach.php",
      'uri'      => "urn://tyler/req"));

$client_pinefalls = new SoapClient(null, array(
      'location' => "http://localhost/soap/server_pinefalls.php",
      'uri'      => "urn://tyler/req"));

$client_selkirk = new SoapClient(null, array(
      'location' => "http://localhost/soap/server_selkirk.php",
      'uri'      => "urn://tyler/req));

Here, each of the three SOAP clients are created with each pointing to one of the three locations for each of the three dealership cities.

Looking up vehicles from each SOAP server

With the three clients created, you can now call the SOAP server's vehicleLookup methods and start returning results! Continue defining the client.php file, as shown below.

Listing 14. Retrieving responses from each SOAP server
      'uri'      => "urn://tyler/req"));

$result_steinbach = $client_steinbach->

$result_pinefalls = $client_pinefalls->

$result_selkirk = $client_selkirk->

Notice how each response for each call to each client's __soapCall is stored. The __soapCall method accepts two parameters you're interested in. The first is the name of the method in the SOAP server you're calling and the other is the array of parameters you're passing.

Displaying results

Now that you've got results, you can display them. Finish defining the client.php file, as shown below.

Listing 15. Displaying search results to the car customer
$result_selkirk = $client_selkirk->

if($result_steinbach != '' ||
   $result_pinefalls != '' || 
   $result_selkirk != ''){
    print "<table>";
    print "<td><b>Year</b></td>";
    print $result_steinbach;
    print $result_pinefalls;
    print $result_selkirk;
    print "</table>";

If one of the three dealerships (SOAP servers) returns results, display the table, with the results from each of the three dealerships as rows. Preview current results below.

Figure 6. Search results
Search results
Search results

When you finish defining the server in the next section, the output will display results, rather than just echo.

The server

Now you'll develop the SOAP server. The three SOAP servers get called by the client code, and each of them returns results, as found in their own local databases. In this section, you'll develop the server by connecting to and querying the Derby database, and returning formatted results.

Connecting to Derby

Before the database can be queried, you need to connect to it in PHP. Define a handy db_connect function in all three sever files, as shown below.

Listing 16. Connecting to the DEALER database

function db_connect($dbname='DEALER',
    $pdo = new PDO("odbc:$dbname", $username, $password);
    return $pdo;

function vehicleLookup($make, $model, $year){

Now whenever you call this method, PHP will connect to the database and return a PHP data object. To learn more about PHP data objects and their capabilities, see Related topics.

Creating the database query

Here's where you're going to modify the vehicleLookup method so you can query the database for results, rather than just sending back to the client what came in. Modify the vehicleLookup method in each of the three server files, as shown below.

Listing 17. Creating SQL for database query
function vehicleLookup($make, $model, $year){
    $pdo = db_connect();
    $queryMake = '';
    $queryModel = '';
    $queryYear = '';
    $query = '';

    if($make != '')
        $queryMake = "make='$make'";
    $query = $queryMake;

    if($model != '')
        $queryModel = "model = '$model'";
    if($query != '' && $queryModel != '')
        $query .= " and $queryModel";
    else if($queryModel != '')
        $query = $queryModel;

    if($year != '')
        $queryYear = " yyear = '$year' ";
    if($query != '' && $queryYear != '')
        $query .= " and $queryYear";
    else if($queryYear != '')
        $query = $queryYear;

    $sql = "select * from ".TABLE." where $query";

First you retrieve the PHP data object from connecting to the database. Then you check each of the three parameters to see if they have contents (meaning that they are not equal to the null string). If they do, append them to the $query string, which you'll use in the where clause of the SQL statement. The code needed for $make is easy and gets slightly more complex with $model and $year. For the latter two cases, if $query and the parameter aren't empty, append them to the where clause with and as the suffix. Otherwise, if the parameter isn't empty, set it to $query, and do nothing if both $query and the parameter are empty. Finally, create the SQL statement by selecting from the table, inserting $query as the value for the where clause.

Querying the database and formatting results

Now that the SQL statement is prepared and ready for use in querying the database, you'll query the database, as shown below.

Listing 18. Querying the database and formatting results
    $sql = "select * from ".TABLE." where $query";

    $ret = '';
    foreach($pdo->query($sql) as $row){
        $make = $row['MAKE'];
        $model = $row['MODEL'];
        $year = $row['YYEAR'];
        $price = $row['PRICE'];
        $desc = $row['FEATURE_DESC'];
        $ret .= "<tr><td>$make</td>";
        $ret .= "<td>$model</td>";
        $ret .= "<td>$year</td>";
        $ret .= "<td>$price</td>";
        $ret .= "<td>$desc</td></tr>";
    return $ret;

Set up the return parameter, $ret, by setting it to the null string, or ''. Then query the database in the foreach statement and loop through each of the results, which get stored in $row with each iteration of the loop. The next five statements retrieve the make, model, yyear, price, and description information from the database. The next five statements format these results in a row using HTML. The last statement returns the results to the client, which displays them.

Customizing for each location

Did you notice the use of the TABLE defined in Listing 17? This is what makes each server different from one another as each one queries a different table in the database. Finish off each of the server files by adding the code, as shown below.

Listing 19. Defining the TABLE
define('TABLE', 'vehicles_selkirk');
function db_connect($dbname='DEALER',

Do the above for the server_selkirk.php file and define the TABLE variable as vehicles_pinefalls and vehicles_selkirk for the vehicles_pinefalls.php and vehicles_selkirk.php files, respectively.

View the results of searching for all 2005 vehicles, as shown below.

Figure 7. Searching for all 2005 vehicles
Searching for all 2005 vehicles
Searching for all 2005 vehicles

Excellent! The application's complete, and you're now a PHP SOAP server guru.


You've developed a SOAP server in PHP. Now you can do what Amazon and Google do with Web services by building integrated Web applications with Web services in the infamous PHP programming language. To top it off, you've integrated your Web service with the lightweight capabilities of the Derby database for data query and storage.

Downloadable resources

Related topics


Sign in or register to add and subscribe to comments.

Zone=Open source
ArticleTitle=Build a Web service with PHP