Академический Документы
Профессиональный Документы
Культура Документы
23 May 2006
In the past few years, new Web services have been popping up all over the Internet.
And what better language to build your own Web service in than PHP? With PHP,
you have the advantage of a great scripting language with the power to connect to
databases, an easy development curve that allows for faster development, and high
response times -- thanks to the underlying libraries compiled for performance.
Page 1 of 25
developerWorks
ibm.com/developerWorks
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.
PHP
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 Resources for information about configuring Apache or
IBM's HTTP Server with PHP.
Database
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 Resources 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.
ibm.com/developerWorks
developerWorks
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.
SOAP
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
<SOAP-ENV:Envelope>
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring>Bad Request. Can't find
HTTP_RAW_POST_DATA</faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
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.
Page 3 of 25
developerWorks
ibm.com/developerWorks
ibm.com/developerWorks
developerWorks
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
<?php
function echoo($echo){
return "ECHO: ".$echo;
}
$server = new SoapServer(null,
array('uri' =>
"urn://tyler/res"));
$server->addFunction('echoo');
$server->handle();
?>
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
<SOAP-ENV:Envelope>
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring>Bad Request. Can't find
HTTP_RAW_POST_DATA</faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Your server is now live, but you can only access it via a SOAP client or you'll get
Page 5 of 25
developerWorks
ibm.com/developerWorks
fault errors, as shown above. Now that you know the SOAP server is working, you
can move onto creating a simple client.
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
ibm.com/developerWorks
developerWorks
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
Page 7 of 25
developerWorks
ibm.com/developerWorks
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
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.
ibm.com/developerWorks
developerWorks
start
When the application starts, it's ready to accept connections. Connect to and create
a new database using the Derby ij tool:
java org.apache.derby.tools.ij
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:
connect
'jdbc:derby:net://localhost:1527/DEALER;create=true:
user=dealer;password=dealer;';
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.
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.
Build a Web service with PHP
Copyright IBM Corporation 1994, 2008. All rights reserved.
Page 9 of 25
developerWorks
ibm.com/developerWorks
(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.
ibm.com/developerWorks
developerWorks
steering'),
seats'),
in GPS'),
in TV and DVD player'),
changer');
Your database is finished and ready to be queried by your PHP application, which
you'll begin architecting next.
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.
Page 11 of 25
developerWorks
ibm.com/developerWorks
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
</td></tr>
<tr><td align="center" colspan="2">
<font size="2px"><br>
<center>Copyright 2006, <?php print(COMPANY_NAME) ?></center>
</font>
</td></tr></table>
</body></html>
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
ibm.com/developerWorks
developerWorks
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.
Page 13 of 25
developerWorks
ibm.com/developerWorks
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
ibm.com/developerWorks
developerWorks
require('footer.php');
?>
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.
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.
Page 15 of 25
developerWorks
ibm.com/developerWorks
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.
=> "urn://tyler/req"));
$result_steinbach = $client_steinbach->
__soapCall("vehicleLookup",array($make,$model,$year));
$result_pinefalls = $client_pinefalls->
__soapCall("vehicleLookup",array($make,$model,$year));
$result_selkirk = $client_selkirk->
__soapCall("vehicleLookup",array($make,$model,$year));
...
ibm.com/developerWorks
developerWorks
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->
__soapCall("vehicleLookup",array($make,$model,$year));
if($result_steinbach != '' ||
$result_pinefalls != '' ||
$result_selkirk != ''){
print "<table>";
print
"<tr><td><b>Make</b></td>
<td><b>Model</b></td>";
print "<td><b>Year</b></td>";
print
"<td><b>Price</b></td><td>
<b>Description</b></td></tr>";
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
Page 17 of 25
developerWorks
ibm.com/developerWorks
When you finish defining the server in the next section, the output will display
results, rather than just echo.
Connecting to Derby
ibm.com/developerWorks
developerWorks
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
<?php
function db_connect($dbname='DEALER',
$username='dealer',
$password='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
Resources.
Page 19 of 25
developerWorks
ibm.com/developerWorks
...
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.
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.
ibm.com/developerWorks
developerWorks
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
<?php
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
Page 21 of 25
developerWorks
ibm.com/developerWorks
Excellent! The application's complete, and you're now a PHP SOAP server guru.
Section 8. Summary
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.
ibm.com/developerWorks
developerWorks
Downloads
Description
Name
Size
Download method
Source code
os-php-webservice.source.zip
5KB
HTTP
Page 23 of 25
developerWorks
ibm.com/developerWorks
Resources
Learn
Explore the differences between the open source Apache Web server and
IBM's version in "Hosting PHP applications on the IBM HTTP Server."
To find out how to get Apache V2 and PHP V4.x (may also use PHP V5.x)
working together on Linux, see Apache 2 and PHP Installation.
To learn how to install and configure PHP on Windows (some steps are
applicable to Linux), read "Connecting PHP Applications to Apache Derby."
To broaden your PHP skills, check out the "Learning PHP" tutorial series on
building a workflow application.
Learn more about PHP data objects and their capabilities in the PHP Manual.
For an excellent resource to learn more about XML namespaces, read XML
Namespaces Explained.
Visit IBM developerWorks' PHP project resources to learn more about PHP.
Stay current with developerWorks technical events and webcasts.
Check out upcoming conferences, trade shows, webcasts, and other Events
around the world that are of interest to IBM open source developers.
Visit the developerWorks Open source zone for extensive how-to information,
tools, and project updates to help you develop with open source technologies
and use them with IBM's products.
To listen to interesting interviews and discussions for software developers, be
sure to check out developerWorks podcasts.
Get products and technologies
Download Java technology from Sun Microsystems or from IBM.
Innovate your next open source development project with IBM trial software,
available for download or on DVD.
Discuss
Get involved in the developerWorks community by participating in
developerWorks blogs.
ibm.com/developerWorks
developerWorks
Tyler Anderson used to work for DPMG.com, an SEO company, for whom he wrote
proprietary SEO software. He graduated with a degree in computer science from
Brigham Young University in 2004 and has just graduated with a master of science
degree in computer engineering in 2005, also from Brigham Young University. He is
currently an engineer for Stexar Corp., based in Beaverton, Ore.
Page 25 of 25