Amazon Product Advertising API - SOAP + PHP + New Requirements

The most popular thing I've ever written was the SOAP+PHP+Authentication article for Amazon Web Services.

Sad, but true.

As of November 1, 2011, Amazon changed the minimum requirements for its soap services, and in doing so, broke my example. I only know this because of a few comments on my blog post alerting me to the issue, and asking if I had a fix. 

Now, I do.

First, they changed the structure of the request a little bit. You now have a nested parameter object, and the AssociateTag element is required.

Additionally, the Signature, Timestamp, and AWS Access Key Id is now required at the SOAP header level.



function find_match ($search,$section="All",$locale='US'){

        $id='<Your Amazon Access Key ID>';
        $key='<Your Amazon Secret Access Key>';
        $wsdl = "http://ecs.amazonaws.com/AWSECommerceService/2010-11-01/$locale/AWSECommerceService.wsdl";
        $associates_tag = '<Your Amazon Associates Tag>';
 
        //  Create the DigSig for the AWS Call.
        $timeStamp = gmdate("Y-m-d\TH:i:s\Z");
        $string = 'ItemSearch'.$timeStamp;
        $signature = base64_encode(hash_hmac("sha256", $string, $key, True));

        $client = new SoapClient($wsdl);

        $headers = array(
                        new SoapHeader(
                                'http://security.amazonaws.com/doc/2007-01-01/',
                                'AWSAccessKeyId',
                                $id
                                ),
                        new SoapHeader(
                                'http://security.amazonaws.com/doc/2007-01-01/',
                                'Timestamp',
                                $timeStamp
                                ),
                        new SoapHeader(
                                'http://security.amazonaws.com/doc/2007-01-01/',
                                'Signature',
                                $signature
                                )
                        );

        //create the nested request object.

        $params["AssociateTag"] = $associates_tag;
        $params["AWSAccessKeyId"] = $id;

        $params['Request'] = array (
                        "Service"=>"AWSECommerceService",
                        "Operation"=>"ItemSearch",
                        "Keywords"=>$search,
                        "SearchIndex"=>"All",
                        "ResponseGroup"=>"Large",
                        );

        //print_r($params);
        $client->__setSoapHeaders($headers);
        $response = $client->__soapCall('ItemSearch',array($params));





        //If its an array, we have multiple items. If its an object, its a single object.
        //Create a slimmed down array from the reponse w/ the stuff I want in it.

        if (is_array($response->Items->Item) ) {
                foreach ($response->Items->Item as $item) {
                        $toReturn[] =   array(
                                        "Image"=>$item->MediumImage->URL,
                                        "Height"=>$item->MediumImage->Height,
                                        "Width"=>$item->MediumImage->Width,
                                        "Detail"=>$item->DetailPageURL,
                                        "Title"=>$item->ItemAttributes->Title,
                                        "Rating"=>$item->CustomerReviews->AverageRating,
                                        "Reviews"=>$item->CustomerReviews->TotalReviews,
                                        "Price"=>$item->OfferSummary->LowestNewPrice->FormattedPrice
                                        );
                }
                return ($toReturn);
        }elseif (is_object($response->Items->Item) ) {
                $item=$response->Items->Item;
                $toReturn[] =   array(
                                "Image"=>$item->MediumImage->URL,
                                "Height"=>$item->MediumImage->Height,
                                "Width"=>$item->MediumImage->Width,
                                "Detail"=>$item->DetailPageURL,
                                "Title"=>$item->ItemAttributes->Title,
                                "Rating"=>$item->CustomerReviews->AverageRating,
                                "Reviews"=>$item->CustomerReviews->TotalReviews,
                                "Price"=>$item->OfferSummary->LowestNewPrice->FormattedPrice
                                );
                return($toReturn);
        }else {
                return(false);
        }
}

?>
 
Posted by Dustin Hawkins at 11:10

NORMSDIST for the TI-89 Calculator

I have an old version of the TI-89 (circa 1997), and it is conveniently missing the stats functions. 

The most painful of these is the Probability function P(x), which is similar to the NORMSDIST function in excel.

If you want to add it to you TI-89, here is how.

Note: this is based on Microsoft's implementation of NORMSDIST, which can be found here.

We are going to define some functions. If you've never done this before, don't worry. Its easy.


First, we define a helper function tt(x). 

  1. From the Home screen, Hit F4.
  2. Select "Define"
  3. Type this:
    Define tt(x)=(1/(1+.2316419*x))
  4. Hit Enter. It should read 'Done'

Next, we define another helper function zz(x).

  1. From the Home screen, Hit F4
  2. Select "Define"
  3. Type this:
    Define zz(x)=(1/(√(2*Π))*e^(-x^2/2)) 

    **These are the Square Root, Pi, and e^ symbols that are native to the TI-89. Also, its a Negative x, not Minus x.

  4. Hit Enter. It should read 'Done'

Finally, we define the probability function prob(x). You can rename this to normsdist, but its to long for my tastes

  1. From the Home screen, Hit F4
  2. Select "Define"
  3. Type this:
    Define prob(x)=(1-zz(x)*(0.31938153*tt(x)+ -0.356563782*(tt(x)^2)+1.781477937*(tt(x)^3)+-1.821255978*(tt(x)^4)+1.330274429*(tt(x)^5))

    **These are negative numbers, not subtraction symbols, so make sure you use the proper key on the TI-89 or it will give you an error

  4. Hit Enter. It should read 'Done'

Check you work on the TI-89

To use a function just type it in like such

tt(.625)  and press Enter.


tt(.625) = .8735

zz(.625) = .3281

prob(.625) =  .734

And in Excel:

=NORMSDIST(.625) = .734 

You never need to use tt(), zz(), they're just helper functions.

Posted by Dustin Hawkins at 16:33 | Comments (2) | Trackbacks (0)

Sniffing the Wire - HTTP Debugging the easy and hard way

If you work in web services for any length of time, eventually you'll need to sniff the packets that are flowing and figure out what [insert framework of choice] is doing to your precious data.

Fear not, there is an easy way. For the sadists, there is also a hard way.

Read on, I'll show you both.


Continue reading "Sniffing the Wire - HTTP Debugging the easy and hard way"

Posted by Dustin Hawkins at 16:15 | Comment (1) | Trackbacks (0)

Newest Mexia Addition

Looks like our little longhorn is finally starting to live up to her name...

Posted by Dustin Hawkins at 19:35 | Comments (0) | Trackbacks (0)

Testing Bandwith between two computers on a LAN

I was having some problems with the bandwidth between my Xbox360 and my Windows 7 Media Center. The connection is via a 87 foot long Cat5e cable that runs though my attic, so the stuttering and slow connection was a bit confusing. At first I thought something might have chewed through the cable, but figured I would test the bandwidth first.

Enter xJperf, a great Java front end for IPerf that comes with a pre-compiled Win32 IPerf binary.

It runs in a client/server mode, so with the use of a laptop (client) and my Windows 7 Desktop (server), I was able to see that my bandwidth was in fact terrible. A new realtek driver, some cable swapping, the disabling of Windows 7 Firewall, and a reboot yielded a 4x increase in bandwidth over the link. 

xJperf is now my second favorite network tool, behind the ever present Wireshark. 

Posted by Dustin Hawkins at 12:09 | Comments (0) | Trackbacks (0)

Amazon Web Services + PHP + SOAP + Authentication

I've created a couple of AWS enabled plugins for Serendipity before, but when Amazon started requiring Signed Request, I never got around to updating them. When I did, I had all kinds of hell making the standard HTTPS post work.

I decided to try my hand at converting it over to soap, which was a lot quicker and easier than I thought. I created a customized amazon search page using my newfound soap skills. Keep reading to see the rest of the code.


Continue reading "Amazon Web Services + PHP + SOAP + Authentication"

Posted by Dustin Hawkins at 12:02 | Comments (7) | Trackbacks (0)
(Page 1 of 1, totaling 6 entries)