Skip to content

Instantly share code, notes, and snippets.

@hubgit
Last active March 4, 2022 02:55
Show Gist options
  • Save hubgit/6006877 to your computer and use it in GitHub Desktop.
Save hubgit/6006877 to your computer and use it in GitHub Desktop.
PHP client for Amazon's Product Advertising API
<?php
date_default_timezone_set('UTC');
// Create keys at https://console.aws.amazon.com/iam/home?#security_credential
class AmazonClient {
/** @var cURL */
public $curl;
public $debug = false;
private $version;
private $host;
private $path = '/onca/xml'; // turn into a host-keyed array if needed
private $config = array();
// constructor
public function __construct($host = 'webservices.amazon.com', $version = '2011-08-01') {
$this->host = $host;
$this->version = $version;
$this->configure();
$this->curl = curl_init();
curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->curl, CURLOPT_ENCODING, 'gzip');
//curl_setopt($this->curl, CURLOPT_VERBOSE, true);
}
// GET request
public function get($params = array()) {
$params['AWSAccessKeyId'] = $this->config['access_key'];
$params['AssociateTag'] = $this->config['associate_tag'][$this->host];
$params['Version'] = $this->version;
$params['Timestamp'] = date('c');
$params['Service'] = 'AWSECommerceService';
$params['Signature'] = $this->sign('GET', $params);
$url = 'http://' . $this->host . $this->path . '?' . $this->build_query($params);
if ($this->debug) {
print "$url\n";
}
curl_setopt($this->curl, CURLOPT_URL, $url);
return $this->exec();
}
// read configuration from ~/.config/amazon.ini
protected function configure() {
$configFile = getenv('HOME') . '/.config/amazon.ini';
if (!file_exists($configFile)) {
printf("Config file %s does not exist\n", $configFile);
exit();
}
$this->config = parse_ini_file($configFile);
foreach (array('access_key', 'access_secret') as $field) {
if (!isset($this->config[$field])) {
printf("Add %s to %s\n", $field, $configFile);
exit();
}
}
foreach (array('associate_tag') as $field) {
if (!isset($this->config[$field][$this->host])) {
printf("Add %s[%s] to %s\n", $field, $this->host, $configFile);
exit();
}
}
}
// send the request and parse the response
protected function exec() {
$result = curl_exec($this->curl);
$code = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
switch ($code) {
case 200:
$dom = new DOMDocument;
$dom->preserveWhiteSpace = false;
$dom->loadXML($result);
if ($this->debug) {
$dom->formatOutput = true;
print $dom->saveXML();
}
$xpath = new DOMXPath($dom);
$xpath->registerNamespace('a', 'http://webservices.amazon.com/AWSECommerceService/' . $this->version);
return $xpath;
default:
print "Error $code\n";
print $result;
return null;
}
}
// build the request signature
protected function sign($verb = 'GET', $params = array()) {
ksort($params);
$request = implode("\n", array($verb, $this->host, $this->path, $this->build_query($params)));
$signature = hash_hmac('sha256', $request, $this->config['access_secret'], true);
return base64_encode($signature);
}
// build the query string, using '%20' for spaces
protected function build_query($params = array()) {
return http_build_query($params, null, '&', PHP_QUERY_RFC3986);
}
}
<?php
require __DIR__ . '/AmazonClient.php';
$client = new AmazonClient;
$params = array(
'Operation' => 'BrowseNodeLookup',
'BrowseNodeId' => '154606011', // Kindle eBooks
'ResponseGroup' => 'TopSellers,MostGifted,NewReleases',
);
$xpath = $client->get($params);
$sets = array();
foreach ($xpath->query('a:BrowseNodes/a:BrowseNode/a:TopItemSet') as $topItemSet) {
$items = array();
foreach ($xpath->query('a:TopItem', $topItemSet) as $topItem) {
$items[] = array(
'url' => $xpath->evaluate('string(a:DetailPageURL)', $topItem),
'title' => $xpath->evaluate('string(a:Title)', $topItem),
'author' => $xpath->evaluate('string(a:Author)', $topItem),
);
}
$sets[] = array(
'type' => $xpath->evaluate('string(a:Type)', $topItemSet),
'items' => $items,
);
}
//print_r($sets);
<?php
require __DIR__ . '/AmazonClient.php';
$client = new AmazonClient;
$params = array(
'Operation' => 'ItemSearch',
'BrowseNode' => '154606011', // Kindle eBooks
'ResponseGroup' => 'ItemAttributes,Reviews,Similarities,EditorialReview,Images',
'SearchIndex' => 'Books', // KindleStore
'Sort' => 'reviewrank',
//'Keywords' => $_GET['keywords'],
);
$items = array();
foreach (range(1, 10) as $page) {
$params['ItemPage'] = $page;
$xpath = $client->get($params);
foreach ($xpath->query('a:Items/a:Item') as $item) {
$itemAttributes = $xpath->query('a:ItemAttributes', $item)->item(0);
$pages = $xpath->evaluate('number(a:NumberOfPages)', $itemAttributes);
$items[] = array(
'url' => $xpath->evaluate('string(a:DetailPageURL)', $item),
'image' => $xpath->evaluate('string(a:LargeImage/a:URL)', $item),
'reviews' => $xpath->evaluate('string(a:CustomerReviews/a:IFrameURL)', $item),
'title' => $xpath->evaluate('string(a:Title)', $itemAttributes),
'author' => $xpath->evaluate('string(a:Author)', $itemAttributes),
'pages' => is_nan($pages) ? null : $pages,
);
}
}
//print_r($items);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment