I’ve recently started using Amazon Web Services (AWS) to import large amounts of rich content into my weekend-warrior project, ThumbSticks.com. I have to say that I’m quite impressed with Amazon’s dedication to providing their product information in such a transparent and detailed manner. If you’re not familiar with AWS, here is a quick introduction and some useful code snippets to help you get started with AWS in your PHP environment.
What is AWS?
Amazon Web Services is a set of web services provided by Amazon.com free of charge. Basically, you can query Amazon’s vast database of information to obtain product details, reviews, images, and just about any other information you can imagine related to any product sold at Amazon.com. In this example, we’re specifically looking at Amazon’s REST web services, which is data that can be retrieved via a unique URL request to the AWS servers. If your web project involves any product-related data, AWS is definitely worth a look. Enriching your existing pages with information retrieved through AWS can augment the utility of your content, making it more useful for your users, and ultimately more important to everyone. If you’re the entrepreneurial type, you can also make commission by letting your users click through to Amazon.com in an attempt to sell their products. It’s win-win for everyone.
How it Works
Getting information from AWS is easy. First of all, you’ll have to set up an AWS account and also sign up for the Amazon Associates program. After signing up for these two programs, you should have all the information you need to make a web services request from your application.
In a nutshell, you make a request that includes things like the product type, query type, and keywords that you’re searching for. All of this information is bundled into a tidy URL structure that allows you to make flexible requests from just about any development platform out there. Once you’ve made a request, what you get back is an XML document that contains the product information you’re interested in.
The Request URL
Generating a request URL is actually more complex than I thought it would be. There are a number of elements that are required in the URL, and some elements even need to be encrypted and escaped in a very specific order. After digging through some blog posts and AWS documentation, I came up with this very handy PHP function that generates an AWS request URL in a fairly easy and configurable fashion.
<?
function awsRequest($searchIndex, $keywords, $responseGroup = false, $operation = "ItemSearch", $pageNumber = 1){
$service_url = "http://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService";
$associate_tag = "your-associate-tag";
$secret_key = "YOUR_SECRET_KEY";
$access_key = "YOUR_ACCESS_KEY";
// build initial request uri
$request = "$service_url&Operation=$operation&AssociateTag=$associate_tag&SearchIndex=$searchIndex&Keywords=".urlencode($keywords)."&ItemPage=$pageNumber";
// parse request into params
$uri_elements = parse_url($request);
$request = $uri_elements['query'];
parse_str($request, $parameters);
// add new params
$parameters['Timestamp'] = gmdate("Y-m-d\TH:i:s\Z");
$parameters['Version'] = $version;
$parameters['AWSAccessKeyId'] = $access_key;
if($responseGroup){
$parameters['ResponseGroup'] = $responseGroup;
}
ksort($parameters);
// encode params and values
foreach($parameters as $parameter => $value){
$parameter = str_replace("%7E", "~", rawurlencode($parameter));
$value = str_replace("%7E", "~", rawurlencode($value));
$request_array[] = $parameter . '=' . $value;
}
$new_request = implode('&', $request_array);
// make it happen
$signature_string = "GET\n{$uri_elements['host']}\n{$uri_elements['path']}\n{$new_request}";
$signature = urlencode(base64_encode(hash_hmac('sha256', $signature_string, $secret_key, true)));
// return signed request uri
return "http://{$uri_elements['host']}{$uri_elements['path']}?{$new_request}&Signature={$signature}";
}
?>
What Now?
Now that you’ve added this function to your PHP application, you’re probably wondering, “What now?” This PHP function merely generates a signed URL by which you can make requests to the AWS web service. Now that this function is in place, you can actually call the web services like so:
// make the request
$xml = simplexml_load_file(awsRequest("VideoGames", "call of duty", "Images", "ItemSearch", "1"));
// now retrieve some data
$totalPages = $xml->Items->TotalPages;
echo "<p>There are $totalPages pages in the XML results.</p>";
// retrieve data in a loop
echo "<ul>\n";
foreach($xml->Items->Item as $item){
echo "<li>".$item->ASIN."</li>\n";
}
echo "</ul>\n";
The resulting output should show the total number of pages as well as an unordered list that contains the ASIN (Amazon’s unique item number) for each product that was returned in our result set. In our request function, we requested image-related data from Amazon’s VideoGame database using the keywords call of duty. We also requested results starting at page 1 of the result set.
Go Deeper
Not sure where to go from here? I highly recommend utilizing the fantastic (and free) Firefox add-on, HttpFox. If you’re making AJAX requests through AWS, you can use HttpFox to monitor the entire XML structure sent back. In my experience, the hardest part working with AWS is figuring out what type of information you want and sorting out their very complex XML structure. Be sure to utilize the AWS developer API as well, as it gives you pivotal information regarding query parameters and data set information to help you fine-tune your requests. I’m currently using the web services to import box art and screenshot images for about 12,000 video games in my database. This process has been made much easier through the use of AWS, and I’m happy to share my revelations with anyone who’s interested.
Good luck, and please let me know if this helps you in any way.
Wonderful post. I was looking for these code for like ages and i found it here.
Thanks for sharing it with us. It really helped me a lot :)
Can you please tell me what are all possible parameters that we can use:
I mean like following are the required ones (atleast one of them):
‘Keywords’,'Title’,'Power’,'BrowseNode’,'Artist’,'Author’,'Actor’,
‘Director’,'AudienceRating’,'Manufacturer’,'MusicLabel’,'Composer’,
‘Publisher’,'Brand’,'Conductor’,'Orchestra’,'TextStream’,'Cuisine’,
‘City’,'Neighborhood’.
Hi, Guarav. The only params that my PHP method will accept are:
searchIndex (required): this is basically the Amazon product “category” you’re searching for; refer to AWS documentation for more info.
keywords (required): this is your search terms; pretty self-explanatory
responseGroup (optional, default=false): the AWS response group you’d like to see (default product info., images, related products, etc.); refer to the AWS documentation for a list of all response groups
operation (optional, default=itemSearch): this is another configurable param of the AWS web services; refer to the AWS documentation for more information
pageNumber (optional, default=1): the results page you’d like to have returned
Hope this helps!
thanks dude, just what i was looking for
thanks for your example. did you ever try the new signature requirement with tying in the old xsl stylesheet parameter?
Hi, Johannes — nope, never used the XSL stylesheet param, but that’s a great feature of the web services. Generally, I transform the XML into HTML via a server-side PHP script, which can in turn use an XSLT file.
thanks for your reply! i’m still puzzled as to the requirement of the ContentType & Style parameters, if they must be included in the signed request or should be added later. right now i can’t seem to get it to work, i got the ItemLookup in general to work though, altering your script at certain places.
Kyle, thanks very much for your contribution. I’m a true PHP newbies and really need an example like this one.
Hi there! Great info.
I was wondering how I can get more than 10 items back from Amazon….
Hey I want to validated the order id of Amazon. If I have an order say
Order ID: 007-4255162-7596541.
I want to make sure I am validating the order id before I insert it into database.
Can you please tell how do I get the product details though xml feed e.g. suppose I want to get Product Name, Price and Description from this page:
http://www.amazon.com/gp/product/0756667526/ref=s9_qpp_gw_p14_ir03?pf_rd_m=ATVPDKIKX0DER&pf_rd_s=center-2&pf_rd_r=0WNR84JB92G1N0R7MAW7&pf_rd_t=101&pf_rd_p=470938631&pf_rd_i=507846
How will i proceed?
Kevin, if you look on Amazon’s web services API (linked in the article above), they give you examples of all types of data that you can get in the XML that comes back from this request. My solution is really only a utility to make the request, it doesn’t do anything with the data. The XML data that you get is different depending on what type of product category and what type of search that you perform, so there’s no way to say exactly how to use this — you’ll definitely have to refer to their documentation for more detailed information on the data that you can use.
Great tutorial. Huge help. Much thanks!
Great Tutorial .. its working fine with get request .. but some of actions are required POST request like for PutUserPolicy and UploadSigningCertificate. Do you have any example for that as well?
Regards
Jayant
Jayant, this is a template for GET requests, I haven’t had the opportunity to come up with a POST request for AWS. Best of luck.
Thank you for this tutorial.was really helpful
It worked great but the code stopped working today.
I got 2 warnings:
[function.simplexml-load-file]: failed to open stream: HTTP request failed! HTTP/1.1 503 Service Unavailable
simplexml_load_file() [function.simplexml-load-file]: I/O warning : failed to load external entity
And the notice:
Trying to get property of non-object in
Do you know what te problem is?
Frans, I’m not sure. It sounds like you’re having connectivity issues or the URL it’s creating is not correct. I haven’t used this in a while, but some of the recent comments make me think it still works for some people.
You’ve got right Kyle. I checked one hour later and it worked again. I didn’t changed a thing on the code. It seems like it was a temporary issue by Amazon.
Thank you soo much, I have been looking for a simple implementation of aws for a long time.