感謝のプログラミング 10000時間

たどり着いた結果(さき)は、感謝でした。

PHPからAmazon Web ServiceのREST APIを利用するサンプル

スポンサーリンク

AmazonのREST APIを使うための準備

Amazonには指定のURLにリクエストを飛ばすことで、商品データを取得できるサービスがある。
このAPIProduct Advertising APIといい、Amazonの取扱商品の検索や購入、商品情報の参照などの機能をWebサイトから利用することができるようになる。

Product Advertising APIを利用するには申し込みが必要で、それは以下のURLから申し込むことができる。
https://affiliate.amazon.co.jp/gp/advertising/api/detail/main.html

上記のURLから
・「アカウントを作成」を選び必要な情報を入力する。
・次に、「Manage Your Account」を選択する。
・アクセスキー情報の「こちらのリンクから、以下の処理が可能です:」をクリック。

「アクセス証明書」
「アクセスキーを使用して、AWSのAPIへのRESTまたはクエリのプロトコルリクエストを確認します。ユーザーアカウントが作成されたときに、アクセスキーが1つ作成されます。下のアクセスキーを確認してください」
のところで、
「新しいアクセスキーを作成する」
をクリック。

そこで取得したアクセスキーとシークレットキーをメモする。

AmazonのREST APIにリクエストを投げて、データを取得するサンプル

今回は「Java」というキーワードを

$keyword = 'java';

のようにベタ書きしている。
こうでもしないと、本を見ながらやったサンプルの出来が素晴らしかったから、完全に写経になってしまう(本は一番下で紹介する)
苦肉の策で、サンプルの機能をそぎ落として自分なりのサンプルにした。
いや、本はすごく勉強になるから、もし検索で辿り着いた人がいたら、実際の本のSECTION20を読んでみてほしい。
では、とりあえずサンプル。

このMyAmazonクラスは、AmazonのAPIにリクエストを投げて、結果を返す機能を持つクラスだ。
インスタンス作成時に必要なIDを渡す。
AmazonのAPIを叩くために使うURLを取得するために、ベースとなるURL(ttp://ecs.amazonaws.jp/onca/xml)に、必要なパラメータをくっつけてくれる。
で、必要なパラメータをくっつけたURLをrequest()メソッドの引数に渡すと、ほしい情報を手に入れることができる。

<?php

class MyAmazon {

	// メンバ変数
	protected $Baseurl;
	protected $access_key_id;
	protected $secret_access_key;
	protected $associate_tag;
	protected $Service;
	public $Version;
	// コンストラクタ
	public function __construct($config){
		$this->setAccessKeyId($config['access_key_id']);
		$this->setSecretAccessKey($config['secret_access_key']);
		$this->setAssociateTag($config['associate_tag']);
		$this->Baseurl = 'http://ecs.amazonaws.jp/onca/xml';
		$this->Service ='AWSECommerceService';
		$this->Version='2010-09-01';
	}

	// アクセスキーセット
	public function setAccessKeyId($access_key_id) {
		$this->access_key_id = $access_key_id;
		return $this;
	}
	// アクセスキー取得
	public function getAccessKeyId() {
		return $this->access_key_id;
	}
	// シークレットアクセスキーセット
	public function setSecretAccessKey($secret_access_key) {
		$this->secret_access_key = $secret_access_key;
		return $this;
	}
	// シークレットアクセスキー取得
	public function getSecretAccessKey() {
		return $this->secret_access_key;
	}
	// アソシエイトタグセット
	public function setAssociateTag($associate_tag) {
		$this->associate_tag = $associate_tag;
		return $this;
	}
	// アソシエイトタグ取得
	public function getAssociateTag() {
		return $this->associate_tag;
	}

	// 「Timestamp」パラメータの時間を取得する
	public  function getTimeStamp() {
		return gmdate('Y-m-d\TH:i:s\Z');
	}


	// 商品検索
	public  function ItemSearch($params = array()){
		return $this->getUrl(
			array_merge(
				array('Operation'=>'ItemSearch'),$params));
	}

	public function getUrl($params = array()){
		return  $this->setUrl(
			array_merge(array(
				'Service' => $this->Service,
				'Version' => $this->Version,
				'AWSAccessKeyId' => $this->getAccessKeyId(),
				'Timestamp' => $this->getTimeStamp(),
				'AssociateTag' => $this->getAssociateTag()
			),$params));
	}

	protected  function setUrl($params = array()){

	    ksort($params);
	    //  canonical stringの作成
	    $canonical_string = '';
	    foreach ($params as $k => $v) {
	        $canonical_string .= '&'.$this->urlencode_rfc3986($k).'='.$this->urlencode_rfc3986($v);
	    }
	    $canonical_string = substr($canonical_string, 1);

	    $parsed_url = parse_url($this->Baseurl);
	    // HMAC-SHA256 を計算
	    $string_to_sign = "GET\n{$parsed_url['host']}\n{$parsed_url['path']}\n{$canonical_string}";
	    // BASE64 エンコード
	    $signature = base64_encode(hash_hmac('sha256', $string_to_sign,  $this->getSecretAccessKey(), true));
	    // リクエストURL作成、末尾に署名を追加
	    $url = $this->Baseurl.'?'.$canonical_string.'&Signature='.$this->urlencode_rfc3986($signature);


	    return $url;
	}

	// APIリクエスト
	public  function request($url){
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
		$response = curl_exec($ch);
		curl_close($ch);

		return simplexml_load_string($response);
	}

	// RFC3986形式でURLエンコード
	public function urlencode_rfc3986($str) {
		return str_replace('%7E', '~', rawurlencode($str));
	}

}
?>

で、上のクラスを使うためのPHPがこちら。

<?php

require_once 'myamazon.php';

$api=new MyAmazon(array(
			'access_key_id' =>'アクセスキー',
			'secret_access_key' =>'シークレットキー',
			'associate_tag' => 'アフィリエイトのID'
		));

//キーワードベタ書き・・・
$keyword = 'java';


$url = $api->ItemSearch(array(
				'ResponseGroup' => 'Medium',
				'SearchIndex'=>'All',
				'Keywords'=> $keyword,
				'ItemPage'=> '5'
			));
	$result= $api->request($url);
	echo json_encode($result);
?>

各パラメータの意味は以下を参照してほしい。
ちなみに、本はサンプルは素晴らしいが、この辺のAPIの情報などはそれほど豊富ではない。
第一歩を踏み出す手助けをしてくれる感じの本だ。

Product Advertising API

Product Advertising API

たとえば、

$url = $api->ItemSearch(array(
				'ResponseGroup' => 'small',
				'SearchIndex'=>'All',
				'Keywords'    => $keyword,
				'ItemPage'=>$ItemPage
			));

のところで使っているパラメータの意味を見てみよう。

ResponseGroup:返される値の種類を指定します。1つのリクエストに複数のレスポンスグループをカンマで区切って指定できます。
SearchIndex:検索対象の商品カテゴリ。多くの ItemSearch パラメータは、特定のSearchIndexでのみ有効です。

となっている。
ResponseGroupにLargeとかSmallとかMediumを設定することで、返ってくる値が違うってことだ。
SearchIndexは、たぶん「本」とか「おもちゃ」とか指定するアレだと思う。

読んだ本

基礎から学ぶ facebookアプリ開発

基礎から学ぶ facebookアプリ開発

そこそこPHPとかJavaScriptjQueryの経験があれば、この本のサンプルはWebアプリを作る上でものすごく参考になる。
非常に今の自分に適したレベルの本で、たいへん助かっている。