A PHP Web Services Client
Pages: 1, 2
Parameters like manufacturer and mode control what you're searching for
— in this case — books manufactured by O'Reilly. The
sort, page, and type options specify
what data is to be returned.
Results can optionally be ordered from best- to worst-selling, alphabetically, by price, and more. (The + in
front of salesrank means ordered from best-selling; -salesrank reverses
the order.) To conserve resources, Amazon
only returns ten items per request. Setting page to 1 means return
books 1 through 10; page 2 has books 11 through 20; and so forth.
If you want more than ten items on your page, just create a loop and increment
page each time through. Also, since Amazon has so much
information, they've created two different DTDs that specify what information
they'll return: lite and heavy. Here, you get the
lite results, which have the product name, author, price, three
different image URLs, and the manufacturer. The heavy DTD has
everything, including all of the posted reviews, any ListMania lists containing
the work, and links to music clips for CDs.
Also, you pass in a tag and a devtag. The tag is an Amazon associate name,
so you can collect referral fees. The devtag is the developer's token you received at the beginning of the article.
You don't need to worry about the parameter order. That's all taken care of
for you behind the scenes. That's not all that's done behind closed doors,
however. When you finally make the request, by calling
$client->ManufacturerSearchRequest($params), PEAR:SOAP converts
your PHP data structures to a SOAP message written in XML and sends an HTTP
request to Amazon's server. After Amazon receives and processes your query, it
replies with a SOAP message of its own. PEAR::SOAP listens for this response
and parses the XML into a PHP object, which is then returned by our method and
stored in $books.
When you're unsure what's in a variable, the easiest way to inspect it is to
use print_r(). Calling print_r($books) echoes:
stdClass Object
(
[TotalResults] => 822
[TotalPages] => 83
[Details] => Array
(
[0] => stdClass Object
(
[Url] => http://www.amazon.com/...
[Asin] => 0596004478
[ProductName] => Google Hacks
[Catalog] => Book
[Authors] => Array
(
[0] => Tara Calishain
[1] => Rael Dornfest
)
[ReleaseDate] => 01 February, 2003
[Manufacturer] => O'Reilly & Associates
[ImageUrlSmall] => http://images.amazon.com/...
[ImageUrlMedium] => http://images.amazon.com/...
[ImageUrlLarge] => http://images.amazon.com/...
[ListPrice] => $24.95
[OurPrice] => $17.47
[UsedPrice] => $15.95
)
[insert nine additional books here]
)
)
The object has three properties: TotalResults, the number of
items that the search matches; TotalPages, the number of times you
need to increment $page and requery Amazon to gather all the data;
and Details, an array containing the actual catalog information.
Each element of Details is itself another array, with the
properties you can use to do things like making your own Amazon store or
printing information about the pile of books next to your bed. (I've shortened
some of the data so it fits nicely in the screen.)
For example, here's a quick-and-dirty loop to create HTML showing the book title, author(s), and price next to a JPEG picture of the cover:
foreach ($hits->Details as $hit) {
$ProductName = html_entities($hit->ProductName);
$Authors = join(' and ', $hit->Authors);
print <<< _HTML_
<div style="clear:left; width: 300px; padding:5px;
margin:5px; background:#ddd;">
<a href="$hit->Url"><image src="$hit->ImageUrlSmall"
alt="$ProductName" align="left"></a>
<b>$ProductName</b><br/>
By $Authors<br/>
Amazon.com Price: $hit->OurPrice<br/>
</div>
_HTML_;
}
This iterates through $hits::Details and places each book
inside of its own <div>. (Of course, a cleaner solution is to place
the style information in a class instead of embedding it inside of each
<div>.) Within the loop, you can pull out the data you want to
show. If it's already formatted how you like, print it directly. Or, if it
needs a little massaging, like the authors array, reformat it, as
is done above by calling join(). You also need to call
html_entities() on ProductName and other text fields,
because you need to encode characters like the & in O'Reilly
& Associates.
You can see the results in Figure 1.

Figure 1. Reformatted book data from the Amazon database
Amazon also allows more complex queries that filter the listings on multiple
criteria. You can use PowerSearchRequest() with Boolean logic to
construct a search. For example, to restrict your O'Reilly search to only books
on PHP:
$params = array(
'power' => "publisher:O'Reilly AND keywords:PHP",
'mode' => 'books',
'sort' => '+title',
'page' => 1,
'type' => 'lite',
'tag' => 'trachtenberg-20',
'devtag' => 'XXXXXXXXXXXXXX',
);
$hits = $client->PowerSearchRequest($params);
Only the first array element has changed. It's now power
instead of manufacturer. Also, its value, publisher:O'Reilly
AND keywords:PHP, makes sure that the publisher is O'Reilly AND that the book
is on PHP. You can also use OR and NOT as well as group expressions using (parenthesis).
Now, the same display function generates new output:

Figure 2. A filtered search
Conclusion
As you've seen, it's very simple to use SOAP and WSDL with PHP. These clients allow you to gather information from across the net to use in your scripts. Amazon.com is not the only major company to provide a SOAP front end to its data. Google lets you search their listings up to 1,000 times a day. Additionally, XMethods has a large directory of SOAP servers that you can experiment with and use.
Adam Trachtenberg is the manager of technical evangelism for eBay and is the author of two O'Reilly books, "Upgrading to PHP 5" and "PHP Cookbook." In February he will be speaking at Web Services Edge 2005 on "Developing E-Commerce Applications with Web Services" and at the O'Reilly booth at LinuxWorld on "Writing eBay Web Services Applications with PHP 5."
|
Related Reading PHP Cookbook |
Return to the PHP DevCenter.
You must be logged in to the O'Reilly Network to post a talkback.
Showing messages 1 through 14 of 14.
-
How Unaware users know about the parameters of the particular web service?
2007-01-29 23:17:47 Raja.p.Nagarajan [Reply | View]
-
How to Invoke ColdFusion Web Service (WSDL) using PHP
2006-04-27 06:38:03 muralid [Reply | View]
Dear Sir,
I am looking for a sample code to Invoke ColdFusion Web Service using PHP Code.
If anyone have the sample code, please send it to me.
Thanks all in Advance.
Murali Krishna D
-
Code also requires HTTP_Request package from pear
2005-12-10 01:43:30 harish020 [Reply | View]
the code explained in the article.. also requires the HTTP_Request package to be installed other than pear..
use
c:\> pear install -a HTTP_Request
-
I want to use wsrp
2005-07-14 02:45:32 spirahesh [Reply | View]
sir,
I want to use wsrp and I want to write my WSRP producer in PHP. is there any package about WSRP, I can use.
Thanks in advance
Sajjad
-
PHP WEB Service usong SOAP
2004-12-30 22:59:18 RMenon [Reply | View]
Sir,
I want to access a web service which is developed using C# and run
on a server (IIS) on my local network. I have php 4.3.9 and Apache Web
Server on my Windows 2000 professional system. I installed PEAR::SOAP
and I can access web services from Amazon etc. But when trying using the
local address, It display errors when calling the getProxy() method of
WSDL_SOAP class.
I am not sure, with my letter you can understand my problem, but I am
very thankful to you for any help regarding this issue.
Thanking you
Ramesh.
-
Apache Axis
2003-09-12 11:37:46 anonymous2 [Reply | View]
Adam, Using the guidelines in this article I am able to connect to web services running on Axis as long as they have simple parameters. My problems are in trying to consume services that take Arrays of Java Structures as parameters. For instance:
in java,
Magazine[] mags = new Magazine[2];
mags[0] = new Magazine("Harpers");
mags[1] = new Magazine("New Yorker");
buySubscriptions(2, mags);
in php,
$magOne = array(
'title' => 'Harpers',
);
$magTwo = array(
'title' => 'New Yorker',
);
$mags[0] = $magOne;
$mags[1] = $magTwo;
$params = array(
'count' => 2,
'mags' => $mags,
);
$response = $client->buySubscriptions($params);
This returns an org.xml.sax.SAXException: No deserializer defined for array type Struct
Any suggestions on how to get this working? Do I need to somehow map the magazine arrays' namespaces?
Thanks,
Ethan -
Apache Axis
2003-09-22 07:58:15 Adam Trachtenberg |
[Reply | View]
Ethan --
Off the top of my head, I'm not sure. It would help if you gave me a pointer to the WS so I could try it myself.
-
quick email?
2003-09-02 19:58:14 anonymous2 [Reply | View]
Adam, sorry to use this forum to contact you, but I could not find an email address for you. I'd like to propose an idea to you that I think you might be interested in...it goes very heavily into the subject of web services and php. If you think you may have enough interest to read a quick 5-paragraph email about it, please get in touch with me at crouchl@lumata.com
Thanks,
-L
-
pear install <pkg> problems
2003-07-25 09:47:16 anonymous2 [Reply | View]
I couldn't get past
pear install SOAP
getting this error:
[root@localhost root]# pear install SOAP
downloading http://pear.php.net/get/SOAP ...
...done: 74,913 bytes
Relation 'has' with requirement '' is not supported
Relation 'has' with requirement '' is not supported
Relation 'has' with requirement '' is not supported
Relation 'has' with requirement '' is not supported
Dependencies failed
---------------------------------------
and that's it - can't get any further.
System:
Red Hat Linux 9
php -v
4.2.2
I did install many dependencies using 'pear install blah', but not sure how to fix these SOAP install errors.
Thanks.
Hardy Merrill
Red Hat, Inc. -
pear install <pkg> problems
2003-08-02 14:04:57 Adam Trachtenberg |
[Reply | View]
I can't reproduce your error on my machine, so I'll have to make some educated guesses:
1) Check which version of pear you are using by running "pear -V". If it's not 1.1, please try upgrading using "pear upgrade pear"
2) PHP 4.2.2 is very old. (Like over a year.) Try upgrading to a newer version, like 4.3.2. (This may also upgrade pear for you as part of the install process.)
If neither of these work, or you really can't do this for some reason, let me know. I have an old Redhat 8.x box I can try and boot up to see if it's some Linux problem. (I'm using Mac OS X.) That seems unlikely, but possible.
-adam
-
little typo
2003-07-04 17:57:56 anonymous2 [Reply | View]
To be current for PHP 4.3.2, html_entities should read htmlentities (delete the underscore.)
Thanks, Adam for a helpful example.
Mat
www.phpconsulting.com
-
little typo
2003-07-21 13:06:00 Adam Trachtenberg |
[Reply | View]
Mat --
Yup. You're correct. I mixed the function's naming convention with html_entity_decode(), its sister.
-adam -
little typo
2004-11-07 21:35:53 stimms [Reply | View]
I also ran into a small issue if authors was undefined. Checking for the existance of authors seemed to help
if($hit->Authors)
$Authors = implode(" and ", $hit->Authors);
I also noticed that the results of the query were stored in $books at first and then jumped to being stored in $hits.




Suppose one new user trying to access some web service in REST way. But he/she dont have clear idea about the parameters need to pass to that web service.
I read one statement from one site.In that WSDL not important for REST based web services. So how can new user aware of parameters need to pass to a particular web service?