Amazon Product Advertising APIを使って、キーワードで商品検索して、「アマゾン商品の検索結果」を取得する

Amazon Product Advertising APIを使って、「アマゾン商品の検索結果」を取得する処理について、PHPソースコードを解説しています。

「アマゾン商品の検索結果」を取得する処理とは、
SearchItemsオペレーションを使って、キーワードで商品検索して、商品情報を取得する処理です。

この記事で紹介しているソースコードは、Product Advertising APIを直接、呼び出しているソースコードになります。

なお、この記事で紹介しているソースコードは、Product Advertising APIのサンプルコードから参照作成したものです。

目次
  1. Amazon Product Advertising APIを使って、キーワードで商品検索して、「アマゾン商品の検索結果」を取得する
  2. Amazon Product Advertising APIのSearchItemsオペレーションで、商品検索リクエストをする場合、ペイロードを作成する
  3. Amazon Product Advertising APIのSearchItemsオペレーションで、商品検索リクエストをする場合、AwsV4クラスの変数を作成する
  4. Amazon Product Advertising APIのSearchItemsオペレーションで、商品検索リクエストをする場合のヘッダーフィールド
  5. Amazon Product Advertising APIのSearchItemsオペレーションで、商品検索リクエストをする
  6. 「アマゾン商品の検索結果」を取得する
  7. HTTP通信エラーが起きた場合、HTTPリクエスト例外を通知する
  8. 商品検索の結果が0件の場合、商品情報は無いとする

Amazon Product Advertising APIを使って、キーワードで商品検索して、「アマゾン商品の検索結果」を取得する

「アフィリエイト商品表示・WordPressプラグイン」には、SearchIndexRequest.phpというPHPのソースコードがあります。

このソースコードは、

Amazon Product Advertising APIのSearchItemsオペレーションを使って、キーワードで商品検索して、「アマゾン商品の検索結果」を取得するソースコードです。

自作ソースコードではない、SearchIndexRequest.phpのソースコード

このソースコードは、自作したソースコードではありません。
Amazon Product Advertising APIのサンプルコードです。

SearchIndexRequest.phpは、Product Advertising APIのサンプルコードから参照作成(引用して作成)したものです。

このサンプルコードは、以下のウェブサイトで提供されているPHPのサンプルコードです。

<?php

namespace goodsmemo\amazon\withoutsdk;

use goodsmemo\amazon\withoutsdk\SearchItemsRequest;
use goodsmemo\amazon\withoutsdk\AwsV4;
use goodsmemo\exception\HttpRequestException;

require_once GOODS_MEMO_DIR . "amazon/withoutsdk/SearchItemsRequest.php";
require_once GOODS_MEMO_DIR . "amazon/withoutsdk/AwsV4.php";
require_once GOODS_MEMO_DIR . "exception/HttpRequestException.php";

class SearchIndexRequest {

	public static function request(string $partnerTag, string $keyword, string $searchIndex, $resources,
			string $hostname, string $accessKey, string $secretKey, string $regionName) {

		$searchItemRequest = new SearchItemsRequest ();
		$searchItemRequest->PartnerType = "Associates";
		// Put your Partner tag (Store/Tracking id) in place of Partner tag
		$searchItemRequest->PartnerTag = $partnerTag;
		$searchItemRequest->Keywords = $keyword;
		$searchItemRequest->SearchIndex = $searchIndex;
		$searchItemRequest->Resources = $resources;
		$host = $hostname;
		$path = "/paapi5/searchitems";
		$payload = json_encode ( $searchItemRequest );

		// Put your Access Key in place of <ACCESS_KEY> and Secret Key in place of <SECRET_KEY> in double quotes
		$awsv4 = new AwsV4 ( $accessKey, $secretKey );
		$awsv4->setRegionName ( $regionName );
		$awsv4->setServiceName ( "ProductAdvertisingAPI" );
		$awsv4->setPath ( $path );
		$awsv4->setPayload ( $payload );
		$awsv4->setRequestMethod ( "POST" );
		$awsv4->addHeader ( 'content-encoding', 'amz-1.0' );
		$awsv4->addHeader ( 'content-type', 'application/json; charset=utf-8' );
		$awsv4->addHeader ( 'host', $host );
		$awsv4->addHeader ( 'x-amz-target', 'com.amazon.paapi5.v1.ProductAdvertisingAPIv1.SearchItems' );
		$headers = $awsv4->getHeaders ();
		$headerString = "";
		foreach ( $headers as $key => $value ) {
			$headerString .= $key . ': ' . $value . "\r\n";
		}
		$params = array (
				'http' => array (
						'header' => $headerString,
						'method' => 'POST',
						'content' => $payload
				)
		);
		$stream = stream_context_create ( $params );

		$fp = @fopen ( 'https://' . $host . $path, 'rb', false, $stream );

		if (! $fp) {
			$errorMessage = "fopen Exception Occured.";

			$httpStatus;
			if (isset ( $http_response_header )) { // $http_response_header変数は、fopen実行後、PHPが自動的に設定する。
				$httpStatus = $http_response_header [0];
			} else {
				// URLが存在しない場合、変数は未定義らしい。未定義なら、HTTP Status 404 と判断して良さそう。
				$httpStatus = "Variable http_response_header is undefined.";
			}

			$errorMessage .= "http status:" . $httpStatus;
			throw new HttpRequestException ( $errorMessage );
		}

		$responseJSON = @stream_get_contents ( $fp );
		if ($responseJSON === false) {
			throw new HttpRequestException ( "stream_get_contents Exception Occured" );
		}

		$responseObject = json_decode ( $responseJSON );
		if (is_null ( $responseObject )) {
			return NULL;
		}

		if (property_exists ( $responseObject, 'Errors' )) { // $responseObject内にerrorが含まれる場合

			// 検索結果0件の場合、ここに来る。正常処理なので、throw new HttpRequestException()しなくて良い。
			// $errorCodeText: string型。例:"NoResults"という文字列が取得された。
			$errorCodeText = $responseObject->{'Errors'} [0]->{'Code'};
			$errorMessage = $responseObject->{'Errors'} [0]->{'Message'};

			// 検索結果0件以外の場合、Eclipseのデバッグでエラー内容を確認すること。
			$responseObject = NULL; // エラー情報を削除した

			// $errorCode=0;
			// throw new HttpRequestException ( $errorMessage, $errorCode );
		}

		return $responseObject;
	}
}

Amazon Product Advertising APIのサンプルコードについては、処理内容を理解してない部分があります。

「アフィリエイト商品表示・WordPressプラグイン」を作成していた当時、

Amazon Product Advertising APIのサイトが提供しているサンプルコードについては、
使い方がわかれば良い、ということにしていました。

現在改めて、Amazon Product Advertising APIのサイトから提供されているサンプルコードを見たところ、
どのような処理をやっているのか、わからない部分がありました。

サンプルコードの全てを理解できませんが、わかる範囲でサンプルコードを解説してみようと思います。

Amazon Product Advertising APIのSearchItemsオペレーションで、商品検索リクエストをする場合、ペイロードを作成する

public static function request(string $partnerTag, string $keyword, string $searchIndex, $resources,
		string $hostname, string $accessKey, string $secretKey, string $regionName) {

	$searchItemRequest = new SearchItemsRequest ();
	$searchItemRequest->PartnerType = "Associates";
	// Put your Partner tag (Store/Tracking id) in place of Partner tag
	$searchItemRequest->PartnerTag = $partnerTag;
	$searchItemRequest->Keywords = $keyword;
	$searchItemRequest->SearchIndex = $searchIndex;
	$searchItemRequest->Resources = $resources;

中略

	$payload = json_encode ( $searchItemRequest );

以下省略

Amazon Product Advertising APIのSearchItemsオペレーションで、商品検索リクエストをする場合、ペイロードを作成します。

Amazon Product Advertising APIのペイロードとは、APIへのリクエストの一部として送信されるデータのことです。

ちなみに、通信やネットワークの分野においては、
ペイロードとは、宛先などの制御情報を除いた、相手に送る本来のデータのことを指します。

ペイロードを作成するために、$searchItemRequest変数を用意する

ペイロードを作成するために、以下の情報を$searchItemRequest変数に代入します。

  • Product Advertising API アソシエイトタグ($partnerTag変数)
  • SearchItems の Resources Parameter($resources変数)

以上の二つの情報は、「アマゾンの設定」で設定します。

※関連記事:アフィリエイト商品表示・WordPressプラグイン、アフィリエイトの設定、アマゾンの設定

  • 商品検索で使うキーワード($keyword変数)
  • SearchItemsオペレーションの検索インデックス($searchIndex変数)

以上の二つの情報は、当プラグインのショートコードの属性で設定します。

※関連記事:アフィリエイト商品表示・WordPressプラグイン、ショートコードの属性

$searchItemRequest変数を基に、JSON形式のペイロードを作成する

$payload = json_encode ( $searchItemRequest );

json_encode()関数を使って、$searchItemRequest変数を基にJSON形式のペイロードを作成します。

json_encode()関数は、PHPオブジェクトまたは配列をJSON形式に変換する、PHPの組み込み関数です。

作成されたJSON形式のペイロードは、$payload変数に代入されます。

Amazon Product Advertising APIのペイロード

$payload = json_encode ( $searchItemRequest );

Amazon Product Advertising APIのペイロードについては、
中身の各情報を実際に見る方がわかりやすい、と思います。

ペイロードについてなんとなくイメージをつかむために、ペイロードの具体的な中身を見ていただけたら、と思います。

以下に、ペイロードの例を示します。

$searchItemRequest変数の例。

//SearchItemsRequestクラスの宣言
class SearchItemsRequest {
	public $PartnerType;
	public $PartnerTag;
	public $Keywords;
	public $SearchIndex;
	public $Resources;
}

//$searchItemRequest変数の例

$searchItemRequest->PartnerTypeの値。
Associates

$searchItemRequest->PartnerTagの値。
sample-22
仮の値です。

$searchItemRequest->Keywordsの値。
PHPプログラミング
当プラグインのショートコードのkeyword属性に、設定した文字列です。

$searchItemRequest->SearchIndexの値。
All

$searchItemRequest->Resourcesの値。
Arrayの配列
[
[0] => Images.Primary.Large, 
[1] => Images.Primary.Medium, 
[2] => Images.Primary.Small, 
[3] => ItemInfo.ByLineInfo, 
[4] => ItemInfo.Classifications, 
[5] => ItemInfo.Features, 
[6] => ItemInfo.ProductInfo, 
[7] => ItemInfo.Title, 
[8] => Offers.Listings.MerchantInfo, 
[9] => Offers.Listings.Price, 
[10] => Offers.Summaries.LowestPrice
]

$payload変数の例。

{
"PartnerType":"Associates",
"PartnerTag":"sample-22",
"Keywords":"PHP\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0",
"SearchIndex":"All",
"Resources":[
"Images.Primary.Large",
"Images.Primary.Medium",
"Images.Primary.Small",
"ItemInfo.ByLineInfo",
"ItemInfo.Classifications",
"ItemInfo.Features",
"ItemInfo.ProductInfo",
"ItemInfo.Title",
"Offers.Listings.MerchantInfo",
"Offers.Listings.Price",
"Offers.Summaries.LowestPrice"]
}

上記の$payload変数の内容は、JSON形式です。

JSON形式について簡単に言うと、キーと値のペアで構成されたものです。

キーは、文字列です。
値は、文字列、数値、ブール値、配列、その他のJSONオブジェクトです。

キーと値は、コロン( : )で区切ります。

JSON オブジェクトは、波括弧{}で囲みます。
キーと値のペアが複数ある場合、カンマ( , )で区切ります。

配列は、角括弧[]で囲みます。
配列の要素は、カンマ( , )で区切ります。

ペイロードのPartnerTypeパラメーター

PartnerTypeパラメーターは、アマゾンプログラムの種類を指定する一般的な要求パラメーターです。

アマゾンアソシエイトのプログラムを指定する場合、Associatesと指定すれば良いようです。

ペイロードのPartnerTagパラメーター

PartnerTagパラメーターは、Amazon Product Advertising APIで、パートナーを一意に識別する英数字のトークンです。

アマゾンアソシエイトの場合、このトークンを使用してアソシエイトを識別して、販売のクレジットを付与します。

PartnerTagは、アマゾンのアソシエイトタグのことです。

アソシエイトタグによる識別が有効な状態で、アマゾンの商品が売れた場合、アフィリエイトの報酬をもらえます。

ペイロードのKeywordsパラメーター

ペイロードにおいてKeywordsパラメーターは、Amazon Product Advertising APIの特定のフィールドではありません。

ただし、キーワードに基づいてアイテムを検索するために使用できます。

なぜだかわかりませんが、Keywordsパラメーターについて調べたところ、
ペイロードにおいては特定のフィールドではない、と言われています。

だけど、たぶんSearchItemsオペレーションの場合は、
Keywordsパラメーターは有効である、と思います。

ペイロードのSearchIndexパラメーター

SearchIndexパラメーター(検索インデックス)は、ペイロード内のパラメーターです。

SearchIndexは、検索する項目のカテゴリ、またはサブカテゴリを指定するために使用されます。

SearchIndexがAllの場合、利用可能な全ての検索インデックスから商品を返します。

利用可能な検索インデックスには、例えば以下のような検索カテゴリがあります。

検索インデックスの値検索カテゴリ
All全ての商品
Books和書
Electronicsエレクトロニクス
Kitchenホーム&キッチン
Toysおもちゃ
HealthPersonalCareヘルスケア
Beautyコスメ
Grocery食品
Apparelアパレル&ファッション雑貨
Hobbiesホビー
検索インデックス

ペイロードのResourcesパラメーター

ペイロードのResourcesパラメーターについては、特に説明を見つけることができませんでした。

たぶん、ペイロードにResourcesパラメーターを指定することで、Amazon Product Advertising APIが返す値のタイプを指定できます。

APIが返す値とは、「アマゾン商品の検索結果」です。

Amazon Product Advertising APIのResourcesには、例えば以下のリソースがあります。

ResourcesResourcesの説明
Images.Primary.Large
Images.Primary.Medium
Images.Primary.Small
Imagesリソースは、商品の利用可能な全ての画像のURLを返します。
これには、Small、Medium、Largeの3つのサイズが含まれます。

また、ImageSetには、primaryと呼ばれる画像があります。
この画像は、4種類のサイズのスウォッチ画像(素材見本の画像)を取得するために使用されます。
ItemInfo.ByLineInfo商品に関する基本情報を説明する属性のセット。
ItemInfo.Classifications商品を特定のカテゴリに分類するために使用される一連の属性。
ItemInfo.Features商品の主な機能に関する情報。
ItemInfo.ProductInfo商品を説明する属性のセット。
ただし、技術的な側面に関する説明を除きます。
ItemInfo.Title商品名など、商品のタイトル。
Offers.Listings.MerchantInfo出品者に関する情報を提供します。

出品者がAmazonフルフィルメントを提供しているかどうか、
送料無料を提供しているかどうか、
プライム対象かどうか、

以上のような情報を提供します。
Offers.Listings.Price商品の価格。
Offers.Summaries.LowestPrice商品の最低価格。
Amazon Product Advertising APIのResources

Amazon Product Advertising APIのSearchItemsオペレーションで、商品検索リクエストをする場合、AwsV4クラスの変数を作成する

$awsv4 = new AwsV4 ( $accessKey, $secretKey );
$awsv4->setRegionName ( $regionName );
$awsv4->setServiceName ( "ProductAdvertisingAPI" );
$awsv4->setPath ( $path );
$awsv4->setPayload ( $payload );
$awsv4->setRequestMethod ( "POST" );
$awsv4->addHeader ( 'content-encoding', 'amz-1.0' );
$awsv4->addHeader ( 'content-type', 'application/json; charset=utf-8' );
$awsv4->addHeader ( 'host', $host );
$awsv4->addHeader ( 'x-amz-target', 'com.amazon.paapi5.v1.ProductAdvertisingAPIv1.SearchItems' );

AwsV4クラスの変数は、Amazon Product Advertising APIにおける認証目的で使用されます。

  • アクセスキー
  • シークレットキー
  • その他の情報

これら情報を使用して、APIに対して行われた各リクエストの署名を生成して、リクエストヘッダーに含めます。

この署名は、リクエストを処理する前にAmazonのサーバーによって検証されます。

AwsV4クラスは、

  • リクエストが承認されたソースであること
  • 例えば、ワードプレスプラグインからの承認されたHTTPリクエストであること

以上のことを保証するために、使用されます。

AwsV4クラスが作成した署名は、Amazonのサーバーに対する不正アクセスではないことを保証するのに役立ちます。

AwsV4情報を作成するために、以下の情報を$awsv4変数に設定します。

  • Product Advertising API アクセスキー($accessKey変数)
  • Product Advertising API シークレットキー($secretKey変数)
  • Product Advertising API リージョン($regionName変数)
  • Product Advertising API ホスト($host変数)

以上の情報は、「アマゾンの設定」で設定します。

※関連記事:アフィリエイト商品表示・WordPressプラグイン、アフィリエイトの設定、アマゾンの設定

情報が設定されたAwsV4クラスの$awsv4変数

$awsv4変数の例。

//AwsV4クラスの宣言
class AwsV4 {
	private $accessKey = null;
	private $secretKey = null;
	private $path = null;
	private $regionName = null;
	private $serviceName = null;
	private $httpMethodName = null;
	private $queryParametes = array ();
	private $awsHeaders = array ();
	private $payload = "";
	private $HMACAlgorithm = "AWS4-HMAC-SHA256";
	private $aws4Request = "aws4_request";
	private $strSignedHeader = null;
	private $xAmzDate = null;
	private $currentDate = null;

	public function __construct($accessKey, $secretKey) {

		$this->accessKey = $accessKey;
		$this->secretKey = $secretKey;
		$this->xAmzDate = $this->getTimeStamp ();
		$this->currentDate = $this->getDate ();
	}

中略

}

//$awsv4変数の例

$awsv4->accessKeyの値。
SAMPLEUIQALSAKLXXXXX
仮の値

$awsv4->secretKeyの値。
SAMPLEvQnr/XvMjvFxuB4301YuF2WGRXXXXX
仮の値

$awsv4->pathの値。
/paapi5/searchitems

$awsv4->regionNameの値。
us-west-2

$awsv4->serviceNameの値。
ProductAdvertisingAPI

$awsv4->httpMethodNameの値。
POST

$awsv4->queryParametesの値。
[]

$awsv4->awsHeadersの値。
[
[content-encoding] => amz-1.0, 
[content-type] => application/json; charset=utf-8, 
[host] => webservices.amazon.co.jp, 
[x-amz-date] => 20230320T051703Z, 
[x-amz-target] => com.amazon.paapi5.v1.ProductAdvertisingAPIv1.SearchItems, 
[Authorization] => 
AWS4-HMAC-SHA256
Credential=SAMPLEUIQALSAKLXXXXX/20230320/us-west-2/ProductAdvertisingAPI/aws4_request,
SignedHeaders=content-encoding;content-type;host;x-amz-date;x-amz-target,
Signature=SAMPLE8ffbfec91ec8cae4d5da6f5beb58316a9be6ec632f6beefe93f8fXXXXX
]

$awsv4->payloadの値。
{
"PartnerType":"Associates",
"PartnerTag":"sample-22",
"Keywords":"PHP\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0",
"SearchIndex":"All",
"Resources":[
"Images.Primary.Large",
"Images.Primary.Medium",
"Images.Primary.Small",
"ItemInfo.ByLineInfo",
"ItemInfo.Classifications",
"ItemInfo.Features",
"ItemInfo.ProductInfo",
"ItemInfo.Title",
"Offers.Listings.MerchantInfo",
"Offers.Listings.Price",
"Offers.Summaries.LowestPrice"]
}

$awsv4->HMACAlgorithmの値。
AWS4-HMAC-SHA256

$awsv4->aws4Requestの値。
aws4_request

$awsv4->strSignedHeaderの値。
content-encoding;content-type;host;x-amz-date;x-amz-target

$awsv4->xAmzDateの値。
20230320T051703Z
日時の例

$awsv4->currentDateの値。
20230320
日付の例

AwsV4クラスのaccessKey

AwsV4クラスのaccessKey変数に、Amazon Product Advertising APIのアクセスキーを設定します。

Amazon Product Advertising APIのアクセスキーは、APIを利用するために必要な認証情報の一つです。

アクセスキーの使用目的は、API に対して行われたリクエストを認証および承認することです。

アクセスキーはシークレットキーと共に構成されていて、APIリクエストに署名して、検証用のハッシュキーを作成するために使用されます。

AwsV4クラスのsecretKey

AwsV4クラスのsecretKey変数に、Amazon Product Advertising APIのシークレットキーを設定します。

Amazon Product Advertising APIのシークレットキーは、API に対するリクエストを認証するために使用される秘密鍵です。

シークレットキーは、アクセスキーと組み合わせて使用​​されて、API に対して行われたリクエストを認証します。

AwsV4クラスのpath

AwsV4クラスのpathは、
Amazon Product Advertising APIのオペレーションに対するリクエストURIのパスを、示します。

以上より、Amazon Product Advertising APIに対して、SearchItemsオペレーションを実行する際、
AwsV4クラスのpath変数に、/paapi5/searchitemsというパス文字列を指定するようです。

AwsV4クラスのregionName

AwsV4クラスのregionName変数に、us-west-2を設定します。

Amazon Product Advertising APIのリージョン(地域名)は、 Amazonアソシエイトのアカウントの場所に関連付けられています。

日本からAPIにリクエストを行う場合は、以下のように指定します。

Amazonアソシエイトのアカウントの場所Product Advertising APIのホストProduct Advertising APIのリージョン
日本webservices.amazon.co.jpus-west-2
Amazon Product Advertising APIのホストとリージョン

日本なのに「US West」という地域名になっているのは、ちょっと違和感があります。

だけど、シンガポールやオーストラリアも「US West」という地域名になっていました。
だから、「US West」で良さそうです。

リージョンの正しいエンドポイントとは?

Amazon Product Advertising APIにリクエストを行う時は、
リージョンの正しいエンドポイントを指定する必要がある、という説明文がありました。

リージョンの正しいエンドポイントについて、意味がよくわかりませんでした。

ちなみにエンドポイントとは、

  • ネットワークに接続された機器や端末
  • あるいは利用者が直接操作する機器

などを指すことが多い用語です。

以上のことを参考にすると、

リージョンの正しいエンドポイントとは、
APIにリクエストするのを承認された、「ある地域」に存在する「ある機器」を、意味しているのかもしれません。

AwsV4クラスのserviceName

AwsV4クラスのserviceNameについては、特に説明が見当たりませんでした。

サービス名として、
AwsV4クラスのserviceName変数に、ProductAdvertisingAPIという文字列を設定します。

これは、特に問題がないように思えます。

AwsV4クラスのhttpMethodName

Amazon Product Advertising APIは、HTTP POSTメソッドを使用してリクエストを送信します。

そういうことより、
AwsV4クラスのhttpMethodName変数に、POSTという文字列を設定しているようです。

AwsV4クラスのqueryParametes

AwsV4クラスのqueryParametesは、Amazon Product Advertising APIをリクエストする時のクエリパラメータを格納するために、使用されます。

queryParametes変数は、クエリパラメータのキーと値のペアを含む連想配列です。

キーと値のペアがない場合は、queryParametes変数は空の連想配列になります。

AwsV4クラスのawsHeaders

AwsV4クラスのawsHeadersは、
Amazon Product Advertising APIをリクエストする時のヘッダーフィールドを保持する連想配列です。

awsHeaders連想配列の変数は、以下のようなヘッダーフィールドを保持します。

ヘッダーフィールド名ヘッダーフィールドの内容ヘッダーフィールドの内容の説明
content-encodingamz-1.0説明を見つけることはできませんでした。

おそらく、APIに対するリクエストの署名のバージョンを、示す。
content-typeapplication/json; charset=utf-8インターネット経由で送信されるコンテンツがJSON形式であり、UTF-8文字エンコーディングを使用してエンコードされている。

以上のことを示すために使用されるMIMEタイプです。
hostwebservices.amazon.co.jpAmazon Product Advertising APIのホスト
x-amz-date値の例
20230320T051703Z
おそらく、amz-1.0と関係がある情報だと思います。

おそらく、APIに対するリクエストの署名が作成された日時を、示す。

x-amz-dateヘッダーは、次の形式である必要があります。

YYYYMMDDTHHMMSSZ

•YYYYは年
•MMは月(01-12)
•DDは日(01-31)
•Tは時間が続くことを示す記号。
•HHは時間(00〜23)
•MMは分(00〜59)
•SSは秒(00〜59)
•Zは、日時がUTC形式であることを示す。
x-amz-targetcom.amazon.paapi5.v1.ProductAdvertisingAPIv1.SearchItemsおそらく、amz-1.0と関係がある情報だと思います。

APIリクエストが対象とするオペレーションを意味する。
Authorization値の例
AWS4-HMAC-SHA256
Credential=SAMPLEUIQALSAKLXXXXX/20230320/us-west-2/ProductAdvertisingAPI/aws4_request,
SignedHeaders=content-encoding;content-type;host;x-amz-date;x-amz-target,
Signature=SAMPLE8ffbfec91ec8cae4d5da6f5beb58316a9be6ec632f6beefe93f8fXXXXX
このフィールドには、以下の情報が含まれます。

署名に使用したアルゴリズム(AWS4-HMAC-SHA256)。

クレデンシャルスコープ(アクセスキー付き)。
Credential=の項目。

署名済みヘッダーのリスト。
SignedHeaders=の項目。

計算された署名。
Signature=の項目。
Amazon Product Advertising APIのヘッダーフィールド
Authorizationヘッダーフィールドのクレデンシャルスコープ

Authorizationヘッダーフィールドのクレデンシャルスコープは、
アマゾンウェブサービスの署名付きAPIリクエストにおいて、認証情報の範囲を指定するために使用されます。

クレデンシャルスコープは、署名が生成される範囲を制限するために使用されます。
このクレデンシャルスコープには、リージョンとサービス名が含まれます。

クレデンシャルスコープについて、以上のような説明文がありました。

よくわからないのですが、おそらく、

署名の有効範囲は、リージョンとサービス名が示す範囲である、ということを言っている気がします。

クレデンシャルスコープの文字列に含まれている情報は、以下の通りです。

クレデンシャルスコープの文字列の例。

Credential=SAMPLEUIQALSAKLXXXXX/20230320/us-west-2/ProductAdvertisingAPI/aws4_request
クレデンシャルスコープの情報クレデンシャルスコープの情報の説明
値の例
SAMPLEUIQALSAKLXXXXX
Amazon Product Advertising APIのアクセスキー
値の例
20230320
Amazon Product Advertising APIのリクエストの日付
値の例
us-west-2
Amazon Product Advertising APIのリージョン(地域名)
ProductAdvertisingAPIサービス名
aws4_requestたぶん 「アマゾンウェブサービス署名のバージョン4」を示す。
クレデンシャルスコープ

AwsV4クラスのpayload

AwsV4クラスのpayload変数に、JSON形式のペイロードを設定します。

設定されるペイロードについては、

当記事の「見出し」
「$searchItemRequest変数を基に、JSON形式のペイロードを作成する
を参照してください。

AwsV4クラスのHMACAlgorithm

AwsV4クラスのHMACAlgorithm変数に、AWS4-HMAC-SHA256を設定します。

HMACは、Hash-based Message Authentication Codeの略です。

2者が、同じ秘密鍵と同じハッシュ関数を使用して、2者間のメッセージの完全性を保証する暗号化方式です。

HMACの暗号化方式を利用することで、

  • 当プラグインからのAmazon Product Advertising APIに対するHTTPリクエストが、本物であること
  • 送信中に改ざんされていないこと

以上のことが保証されます。

HMACの説明で、鍵の名称が4個出てきました

HMACの解説記事をいくつか読んだところ、鍵の名称で公開鍵や共有鍵、暗号鍵という名称を使って説明している記事もありました。

HMACの説明において公開鍵と秘密鍵、共有鍵と暗号鍵、どの鍵の名称を使えば良いのか、あんまりよくわかりませんでした。

HMACの暗号化方式については、専門書籍で学ぶ方が良さそうです。

HMACがデータの整合性と認証を保証する方法

参考に、HMACがデータの整合性と認証を保証する方法について、以下に書きます。

HMACは、秘密鍵と暗号化ハッシュ関数を使用して、認証対象データのメッセージ認証コード(MAC)を生成することにより、データの整合性と認証を保証します。

HMACは、送信者と受信者の両方で同じ対称鍵を使用して、許可された関係者のみがMACを生成および検証できるようにします。

対称鍵とは、データの暗号化と復号化に使用される暗号鍵(ここでは秘密鍵)のことを言います。

許可された関係者とは、同じ秘密鍵と同じ暗号化ハッシュ関数を知っている送信者と受信者のことを言います。

  1. 送信者は、データと共にMACを受信者に送信します。
  2. 受信者は、同じ秘密鍵と同じ暗号化ハッシュ関数を使用して、受信したデータのMACを生成できます。
  3. 受信者によって生成されたMACが、送信者によって送信されたMACと一致する場合、データは本物と判断できます。

以上より、データは送信中に改ざんされていないことを保証できます。
送信者と受信者は、許可された関係者であることを保証できます。

1番において送信者(当プラグイン)は、
Amazon Product Advertising APIのアクセスキー付きのAuthorizationヘッダーフィールドのクレデンシャルスコープを、受信者(アマゾン)に送信しているように思えます。

アクセスキーは公開鍵なので、
それと対になる秘密鍵(Amazon Product Advertising APIのシークレットキー)を、受信者(アマゾン)は特定できるように思えます。

つまり、受信者(アマゾン)はアクセスキーによって、
送信者(当プラグイン)と同じ秘密鍵(Amazon Product Advertising APIのシークレットキー)を特定できるように思えます。

AwsV4クラスのaws4Request

AwsV4クラスのaws4Request変数に、aws4_requestを設定します。

aws4_requestという文字列について、説明を見つけることができませんでした。

もしかしたら、「アマゾンウェブサービス署名のバージョン4」という意味を、表しているのかもしれません。

Amazon Product Advertising APIのHTTPリクエストの署名に関する情報だと思います。

AwsV4クラスのstrSignedHeader

AwsV4クラスのstrSignedHeaderは、署名済みヘッダーのリストです。

AwsV4クラスのstrSignedHeader変数に、
content-encoding;content-type;host;x-amz-date;x-amz-target
を設定します。

署名済みヘッダーのリストは、小文字のヘッダーフィールド名をセミコロンで区切ったリストです。

小文字のヘッダーフィールド名のみを抽出することは、おそらく、
「アマゾンウェブサービス署名のバージョン4」で指定された形式です。

AwsV4クラスのxAmzDate

AwsV4クラスのxAmzDateは、Amazon Product Advertising APIリクエストの日時をUTC形式で指定するために、使用されます。

xAmzDateの日時の例。
20230320T051703Z

このような日時を示す文字列が、AwsV4クラスのxAmzDate変数に設定されます。

AwsV4クラスのxAmzDateについては、

当記事の「見出し」
「AwsV4クラスのawsHeaders
のヘッダーフィールドに関する説明を、参照してください。

ヘッダーフィールド名x-amz-dateの説明も、参照してください。

AwsV4クラスのcurrentDate

AwsV4クラスのcurrentDateは、Amazon Product Advertising APIリクエストの日付です。

currentDateの日付の例。
20230320

このような日付を示す文字列が、AwsV4クラスのcurrentDate変数に設定されます。

currentDateの日付は、署名の構成要素の一つです。
この日付は、署名が限られた期間のみ有効であることを保証するために使用されます。

currentDateは、通常YYYYMMDDという形式の文字列で表されます。

  • YYYYは年
  • MMは月(01-12)
  • DDは日(01-31)

以上の形式の文字列です。

Amazon Product Advertising APIのSearchItemsオペレーションで、商品検索リクエストをする場合のヘッダーフィールド

$headers = $awsv4->getHeaders ();
$headerString = "";
foreach ( $headers as $key => $value ) {
	$headerString .= $key . ': ' . $value . "\r\n";
}

Amazon Product Advertising APIをリクエストする時のヘッダーフィールドを作成します。

作成されたヘッダーフィールドは、$headerString変数に代入されます。

ヘッダーフィールドを保持する$headers連想配列の変数

$headers連想配列の変数の例。

[
[content-encoding] => amz-1.0, 
[content-type] => application/json; charset=utf-8, 
[host] => webservices.amazon.co.jp, 
[x-amz-date] => 20230320T051703Z, 
[x-amz-target] => com.amazon.paapi5.v1.ProductAdvertisingAPIv1.SearchItems, 
[Authorization] => 
AWS4-HMAC-SHA256 
Credential=SAMPLEUIQALSAKLXXXXX/20230320/us-west-2/ProductAdvertisingAPI/aws4_request,
SignedHeaders=content-encoding;content-type;host;x-amz-date;x-amz-target,
Signature=SAMPLE8ffbfec91ec8cae4d5da6f5beb58316a9be6ec632f6beefe93f8fXXXXX
]

$headers連想配列の変数については、

当記事の「見出し」
「AwsV4クラスのawsHeaders
のヘッダーフィールドに関する説明を、参照してください。

ヘッダーフィールドを保持する$headerString変数

$headerString変数の例。

content-encoding: amz-1.0
content-type: application/json; charset=utf-8
host: webservices.amazon.co.jp
x-amz-date: 20230320T051703Z
x-amz-target: com.amazon.paapi5.v1.ProductAdvertisingAPIv1.SearchItems
Authorization: AWS4-HMAC-SHA256 Credential=SAMPLEUIQALSAKLXXXXX/20230320/us-west-2/ProductAdvertisingAPI/aws4_request,SignedHeaders=content-encoding;content-type;host;x-amz-date;x-amz-target,Signature=SAMPLE8ffbfec91ec8cae4d5da6f5beb58316a9be6ec632f6beefe93f8fXXXXX

$headerString変数は、Amazon Product Advertising APIをリクエストする時のヘッダーフィールドです。

ヘッダーフィールドの各項目は、以下の形式で構成されます。

ヘッダーフィールド名: ヘッダーフィールドの内容

コロン( : )によって、各項目が区切られています。

ヘッダーフィールドの各項目については、

当記事の「見出し」
「AwsV4クラスのawsHeaders
のヘッダーフィールドに関する説明を、参照してください。

Amazon Product Advertising APIのSearchItemsオペレーションで、商品検索リクエストをする

$params = array (
		'http' => array (
				'header' => $headerString,
				'method' => 'POST',
				'content' => $payload
		)
);
$stream = stream_context_create ( $params );

$fp = @fopen ( 'https://' . $host . $path, 'rb', false, $stream );

//$hostの値
//webservices.amazon.co.jp

//$pathの値
// /paapi5/searchitems

HTTPヘッダー付きのストリームコンテキストを作成する

stream_context_create()関数は、前もって指定されたオプションを使用して、ストリームコンテキストを作成して返す関数です。

PHPでのストリームコンテキストの最も一般的な用途は、HTTPヘッダーの作成です。

stream_context_create()関数を使用して、HTTPヘッダー付きのストリームコンテキストを作成します。

$params変数は、HTTPヘッダーの各情報を保持します。
$stream変数は、HTTPヘッダー付きのストリームコンテキストを保持します。

HTTPヘッダーの各情報を保持する$params変数

$params変数は、ストリームコンテキストのパラメータを指定する連想配列です。
ストリームの動作を構成するために使用されます。

ストリームコンテキストのパラメータ形式は、連想配列の連想配列です。
array['wrapper']['option'] = $value

$params変数の例。

[
[http] => 
  [
    [header] => content-encoding: amz-1.0
    content-type: application/json; charset=utf-8
    host: webservices.amazon.co.jp
    x-amz-date: 20230320T051703Z
    x-amz-target: com.amazon.paapi5.v1.ProductAdvertisingAPIv1.SearchItems
    Authorization: AWS4-HMAC-SHA256 Credential=SAMPLEUIQALSAKLXXXXX/20230320/us-west-2/ProductAdvertisingAPI/aws4_request,
    SignedHeaders=content-encoding;content-type;host;x-amz-date;x-amz-target,
    Signature=SAMPLE8ffbfec91ec8cae4d5da6f5beb58316a9be6ec632f6beefe93f8fXXXXX, 
    [method] => POST, 
    [content] => 
      {
      "PartnerType":"Associates",
      "PartnerTag":"sample-22",
      "Keywords":"PHP\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0",
      "SearchIndex":"All",
      "Resources":
        [
        "Images.Primary.Large",
        "Images.Primary.Medium",
        "Images.Primary.Small",
        "ItemInfo.ByLineInfo",
        "ItemInfo.Classifications",
        "ItemInfo.Features",
        "ItemInfo.ProductInfo",
        "ItemInfo.Title",
        "Offers.Listings.MerchantInfo",
        "Offers.Listings.Price",
        "Offers.Summaries.LowestPrice"
        ]
      }
  ]
]
パラメータのheaderオプション

[ header ]のヘッダーフィールドの各項目については、

当記事の「見出し」
「AwsV4クラスのawsHeaders
のヘッダーフィールドに関する説明を、参照してください。

パラメータのmethodオプション

[ method ]は、HTTPリクエストで使用されるHTTPメソッドです。

HTTPメソッドをPOSTに設定しています。

パラメータのcontentオプション

[ content ]のペイロードについては、

当記事の「見出し」
「$searchItemRequest変数を基に、JSON形式のペイロードを作成する
を参照してください。

HTTPヘッダー付きのストリームコンテキストを保持する$stream変数

$stream変数は、stream_context_create()関数が作成したストリームコンテキストを、保持します。

このストリームコンテキストは、fopen()関数などのファイルシステム関連の関数に渡すことができます。

$stream変数の例。

resource id='598' type='stream-context'

「アマゾン商品の検索結果」を読み取るためのファイルポインタを、取得する

$fp = @fopen ( 'https://' . $host . $path, 'rb', false, $stream );

//$hostの値
//webservices.amazon.co.jp

//$pathの値
// /paapi5/searchitems

$stream変数が保持する「HTTPヘッダー付きのストリームコンテキスト」を、fopen()関数に設定します。
そうすることで、指定されたヘッダーを持つHTTPリクエストを実行できます。

fopen()関数は、URLの内容を読み取るためのファイルポインタを、返します。

ここで言うURLとは、
https://webservices.amazon.co.jp/paapi5/searchitems
です。

URLの内容とは、「アマゾン商品の検索結果」です。

以上より、fopen()関数から取得したファイルポインタは、
「アマゾン商品の検索結果」を読み取るためのファイルポインタになります。

「アマゾン商品の検索結果」を取得する

$fp = @fopen ( 'https://' . $host . $path, 'rb', false, $stream );

//$hostの値
//webservices.amazon.co.jp

//$pathの値
// /paapi5/searchitems

$responseJSON = @stream_get_contents ( $fp );
if ($responseJSON === false) {
	throw new HttpRequestException ( "stream_get_contents Exception Occured" );
}

$responseObject = json_decode ( $responseJSON );
if (is_null ( $responseObject )) {
	return NULL;
}

JSON形式の「アマゾン商品の検索結果」を取得する

stream_get_contents()関数は、すでにオープンしているストリームに対してデータを取得して、文字列に保存する関数です。

stream_get_contents()関数に対して、
「アマゾン商品の検索結果」を読み取るためのファイルポインタを設定して、実行します。

stream_get_contents()関数から取得した文字列を、$responseJSON変数に代入します。

この取得した文字列は、JSON形式の「アマゾン商品の検索結果」です。

「アマゾン商品の検索結果」のPHPオブジェクトを取得する

json_decode()関数は、JSON文字列をPHPの値に変換します。

json_decode()関数に対して、JSON形式の「アマゾン商品の検索結果」を設定して、実行します。

json_decode()関数から取得したPHPオブジェクトを、$responseObject変数に代入します。

この取得したPHPオブジェクトは、「アマゾン商品の検索結果」を保持するPHPオブジェクトになります。

明示的にfclose($fp)を実行していないけれど、大丈夫でした

PHPでは、fclose()関数が呼ばれなかったストリームについては、そのリソースを自動的に開放します。

Java言語のガベージコレクションみたいな仕組みが、PHPにもありました。

よって、アマゾンのサンプルコードでfclose()関数の記述がなかったけれど、大丈夫です。

だけどそうは言っても、きちんとfclose()関数を実行してリソースを解放する方が、丁寧なソースコードと言えそうです。

JSON形式の「アマゾン商品の検索結果」を保持する$responseJSON変数

$responseJSON変数は、JSON形式の「アマゾン商品の検索結果」を保持しています。

$responseJSON変数の例。

{
"SearchResult":
{
"Items":
[
{
"ASIN":"XXXX000001",
"DetailPageURL":"https://www.amazon.co.jp/dp/4873116686?tag=sample-22&linkCode=osi&th=1&psc=1",
"Images":
{
"Primary":
{
"Large":
{
"Height":500,
"URL":"https://m.media-amazon.com/images/I/XXXXSSmCnjL._SL500_.jpg",
"Width":391
},
"Medium":
{
"Height":160,
"URL":"https://m.media-amazon.com/images/I/XXXXSSmCnjL._SL160_.jpg",
"Width":125
},
"Small":
{
"Height":75,
"URL":"https://m.media-amazon.com/images/I/XXXXSSmCnjL._SL75_.jpg",
"Width":58
}
}
},
"ItemInfo":
{
"ByLineInfo":
{
"Contributors":
[
{
"Locale":"ja_JP",
"Name":"Kevin XXXX",
"Role":"著",
"RoleType":"author"
},
{
"Locale":"ja_JP",
"Name":"Peter XXXX",
"Role":"著",
"RoleType":"author"
},
{
"Locale":"ja_JP",
"Name":"Rasmus XXXX",
"Role":"著",
"RoleType":"author"
},
{
"Locale":"ja_JP",
"Name":"高木 XXXX",
"Role":"翻訳",
"RoleType":"translator"
}
],
"Manufacturer":
{
"DisplayValue":"XXXXジャパン",
"Label":"Manufacturer",
"Locale":"ja_JP"
}
},
"Classifications":
{
"Binding":
{
"DisplayValue":"大型本",
"Label":"Binding",
"Locale":"ja_JP"
},
"ProductGroup":
{
"DisplayValue":"本",
"Label":"ProductGroup",
"Locale":"ja_JP"
}
},
"ProductInfo":
{
"IsAdultProduct":
{
"DisplayValue":false,
"Label":"IsAdultProduct",
"Locale":"en_US"
},
"ItemDimensions":
{
"Height":
{
"DisplayValue":9.448818888,
"Label":"Height",
"Locale":"ja_JP",
"Unit":"インチ"
},
"Length":
{
"DisplayValue":1.574803148,
"Label":"Length",
"Locale":"ja_JP",
"Unit":"インチ"
},
"Weight":
{
"DisplayValue":1.322773572,
"Label":"Weight",
"Locale":"ja_JP",
"Unit":"ポンド"
},
"Width":
{
"DisplayValue":7.480314953,
"Label":"Width",
"Locale":"ja_JP",
"Unit":"インチ"
}
},
"UnitCount":
{
"DisplayValue":1,
"Label":"NumberOfItems",
"Locale":"en_US"
}
},
"Title":
{
"DisplayValue":"プログラミングPHP",
"Label":"Title",
"Locale":"ja_JP"
}
},
"Offers":
{
"Listings":
[
{
"Id":"XXXXuqZV9p%2F9pThe3wpI3Fjh2M8oyA4O1gf5jmywp2AigraEoBosy%2B9UXq31F6Xjpgb2EgfNU9zKiaF%2Bw6VX2ctWetmRXxRdVs8hTELGa8iJBqm%2FTizDYbJueUUaGTkmWesG%2BH%2FF72w%3D",
"MerchantInfo":
{
"FeedbackCount":0,
"FeedbackRating":0.0,
"Id":"AN1VRQENFRJN5",
"Name":"Amazon.co.jp"
},
"Price":
{
"Amount":4180.0,
"Currency":"JPY",
"DisplayAmount":"¥4,180"
},
"ViolatesMAP":false
}
],
"Summaries":
[
{
"Condition":
{
"Value":"Collectible"
},
"LowestPrice":
{
"Amount":8350.0,
"Currency":"JPY",
"DisplayAmount":"¥8,350"
}
},
{
"Condition":
{
"Value":"New"
},
"LowestPrice":
{
"Amount":4180.0,
"Currency":"JPY",
"DisplayAmount":"¥4,180"
}
},
{
"Condition":
{
"Value":"Used"
},
"LowestPrice":
{
"Amount":1066.0,
"Currency":"JPY",
"DisplayAmount":"¥1,066"
}
}
]
}
},

{
"ASIN":"XXXX000002",

中略

},

中略

],
"SearchURL":"https://www.amazon.co.jp/s?k=PHP%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0&rh=p_n_availability%3A-1&tag=sample-22&linkCode=osi",
"TotalResultCount":462
}
}

"SearchResult"の"Items"項目には、最大10個の商品情報があります。

1個の商品情報については、例えば以下のような情報があります。

商品情報の項目商品情報の項目の内容
ASINASIN(Amazon Standard Identification Number)は、アマゾンサイトに掲載している各商品に割り当てる、一意の識別子です。
DetailPageURLアマゾンサイトの商品ページへのURLです。
アソシエイトタグが、URLのクエリパラメーターに付与されています。
ペイロードのResourcesパラメーターで指定した項目例えば、以下のような項目の内容があります。

•商品名
•商品画像のURL
•商品説明
•商品価格
1個の商品情報

ペイロードのResourcesパラメーターで指定した項目ついては、

当記事の「見出し」
「ペイロードのResourcesパラメーター
のResourcesの説明を、参照してください。

「アマゾン商品の検索結果」を保持する、PHPオブジェクトの$responseObject変数

$responseObject変数は、「アマゾン商品の検索結果」のPHPオブジェクトです。

$responseObject変数の例。

stdClass Object 
( 
[SearchResult] => stdClass Object 
( 
[Items] => Array 
( 
[0] => stdClass Object 
(
[ASIN] => XXXX000001
[DetailPageURL] => https://www.amazon.co.jp/dp/4873116686?tag=sample-22&linkCode=osi&th=1&psc=1
[Images] => stdClass Object 
( 
[Primary] => stdClass Object 
( 
[Large] => stdClass Object 
( 
[Height] => 500 
[URL] => https://m.media-amazon.com/images/I/XXXXSSmCnjL._SL500_.jpg 
[Width] => 391 
) 
[Medium] => stdClass Object 
( 
[Height] => 160 
[URL] => https://m.media-amazon.com/images/I/XXXXSSmCnjL._SL160_.jpg 
[Width] => 125 
) 
[Small] => stdClass Object 
( 
[Height] => 75 
[URL] => https://m.media-amazon.com/images/I/XXXXSSmCnjL._SL75_.jpg 
[Width] => 58
)
)
)
[ItemInfo] => stdClass Object 
( 
[ByLineInfo] => stdClass Object 
( 
[Contributors] => Array 
( 
[0] => stdClass Object 
( 
[Locale] => ja_JP 
[Name] => Kevin XXXX 
[Role] => 著 
[RoleType] => author 
) 
[1] => stdClass Object 
( 
[Locale] => ja_JP 
[Name] => Peter XXXX 
[Role] => 著 
[RoleType] => author 
) 
[2] => stdClass Object 
( 
[Locale] => ja_JP 
[Name] => Rasmus XXXX 
[Role] => 著 
[RoleType] => author 
) 
[3] => stdClass Object 
( 
[Locale] => ja_JP 
[Name] => 高木 XXXX 
[Role] => 翻訳 
[RoleType] => translator 
) 
) 
[Manufacturer] => stdClass Object 
( 
[DisplayValue] => XXXXジャパン 
[Label] => Manufacturer 
[Locale] => ja_JP 
) 
) 
[Classifications] => stdClass Object 
( 
[Binding] => stdClass Object 
( 
[DisplayValue] => 大型本 
[Label] => Binding 
[Locale] => ja_JP 
) 
[ProductGroup] => stdClass Object 
( 
[DisplayValue] => 本 
[Label] => ProductGroup 
[Locale] => ja_JP 
) 
) 
[ProductInfo] => stdClass Object 
( 
[IsAdultProduct] => stdClass Object 
( 
[DisplayValue] => false
[Label] => IsAdultProduct 
[Locale] => en_US 
) 
[ItemDimensions] => stdClass Object 
( 
[Height] => stdClass Object 
( 
[DisplayValue] => 9.448818888 
[Label] => Height 
[Locale] => ja_JP 
[Unit] => インチ 
) 
[Length] => stdClass Object 
( 
[DisplayValue] => 1.574803148 
[Label] => Length 
[Locale] => ja_JP 
[Unit] => インチ 
) 
[Weight] => stdClass Object 
( 
[DisplayValue] => 1.322773572 
[Label] => Weight 
[Locale] => ja_JP 
[Unit] => ポンド 
) 
[Width] => stdClass Object 
( 
[DisplayValue] => 7.480314953 
[Label] => Width 
[Locale] => ja_JP 
[Unit] => インチ 
) 
) 
[UnitCount] => stdClass Object 
( 
[DisplayValue] => 1 
[Label] => NumberOfItems 
[Locale] => en_US 
) 
) 
[Title] => stdClass Object 
( 
[DisplayValue] => プログラミングPHP 
[Label] => Title 
[Locale] => ja_JP 
) 
) 
[Offers] => stdClass Object 
( 
[Listings] => Array 
( 
[0] => stdClass Object 
( 
[Id] => XXXXuqZV9p%2F9pThe3wpI3Fjh2M8oyA4O1gf5jmywp2AigraEoBosy%2B9UXq31F6Xjpgb2EgfNU9zKiaF%2Bw6VX2ctWetmRXxRdVs8hTELGa8iJBqm%2FTizDYbJueUUaGTkmWesG%2BH%2FF72w%3D 
[MerchantInfo] => stdClass Object 
( 
[FeedbackCount] => 0 
[FeedbackRating] => 0 
[Id] => AN1VRQENFRJN5 
[Name] => Amazon.co.jp 
) 
[Price] => stdClass Object 
( 
[Amount] => 4180 
[Currency] => JPY 
[DisplayAmount] => ¥4,180 
) 
[ViolatesMAP] => 
) 
) 

[Summaries] => Array 
( 
[0] => stdClass Object 
( 
[Condition] => stdClass Object 
( 
[Value] => Collectible 
) 
[LowestPrice] => stdClass Object 
( 
[Amount] => 8350 
[Currency] => JPY 
[DisplayAmount] => ¥8,350 
) 
) 
[1] => stdClass Object 
( 
[Condition] => stdClass Object 
( 
[Value] => New 
) 
[LowestPrice] => stdClass Object 
( 
[Amount] => 4180 
[Currency] => JPY 
[DisplayAmount] => ¥4,180 
) 
) 
[2] => stdClass Object 
( 
[Condition] => stdClass Object 
( 
[Value] => Used 
) 
[LowestPrice] => stdClass Object 
( 
[Amount] => 1066 
[Currency] => JPY 
[DisplayAmount] => ¥1,066 
) 
) 
) 
) 
) 

[1] => stdClass Object 
(
[ASIN] => XXXX000002

中略

)

中略

[SearchURL] => https://www.amazon.co.jp/s?k=PHP%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0&rh=p_n_availability%3A-1&tag=sample-22&linkCode=osi 
[TotalResultCount] => 462 
) 
)

[ SearchResult ]の[ Items ]配列には、最大10個の商品情報があります。

「アマゾン商品の検索結果」のPHPオブジェクトの内容は、JSON形式の「アマゾン商品の検索結果」の内容と同じです。

PHPオブジェクトの商品情報については、

当記事の「見出し」
JSON形式の「アマゾン商品の検索結果」を保持する$responseJSON変数
の説明を、参照してください。

HTTP通信エラーが起きた場合、HTTPリクエスト例外を通知する

$fp = @fopen ( 'https://' . $host . $path, 'rb', false, $stream );

if (! $fp) {
	$errorMessage = "fopen Exception Occured.";

	$httpStatus;
	if (isset ( $http_response_header )) { // $http_response_header変数は、fopen実行後、PHPが自動的に設定する。
		$httpStatus = $http_response_header [0];
	} else {
		// URLが存在しない場合、変数は未定義らしい。未定義なら、HTTP Status 404 と判断して良さそう。
		$httpStatus = "Variable http_response_header is undefined.";
	}

	$errorMessage .= "http status:" . $httpStatus;
	throw new HttpRequestException ( $errorMessage );
}

fopen()関数によってAmazon Product Advertising APIを呼び出した際、
HTTP通信エラーが起きた場合、HTTPリクエスト例外を通知します。

$http_response_header変数は、多くの場合で、ローカルスコープで自動的に作成される配列です。

if (isset ( $http_response_header ))

上記のisset()関数で、$http_response_header変数の存在を確認します。

isset()関数は、引数に指定した変数において、
NULLではない、かつ、値が設定されている場合、trueを返します。

$http_response_header変数が存在する場合、$http_response_header変数からエラーに関するHTTPステータスコードを取得する

$http_response_header変数が存在する場合、isset()関数はtrueを返します。

HTTP通信エラーが起きた場合で、$http_response_header変数が存在する場合、
$http_response_header変数は、エラーに関するHTTPステータスコードを保持しています。

$http_response_header変数の例。

[
[0] => HTTP/1.1 401 Unauthorized, 
[1] => Server: Server, 
[2] => Date: Wed, 22 Mar 2023 08:19:52 GMT, 
[3] => Content-Type: application/json, 
[4] => Content-Length: 183, 
[5] => Connection: close, 
[6] => x-amz-rid: HS7X0X57W359CFGHNBJ4, 
[7] => x-amzn-RequestId: 7a61c4d7-abc8-470f-b055-8b91b9c17d30, 
[8] => Vary: Content-Type,Accept-Encoding,User-Agent, 
[9] => Strict-Transport-Security: max-age=47474747; includeSubDomains; preload
]

上記の$http_response_header変数の場合、
$http_response_header[0]に、401というHTTPステータスコードがあります。

401は、認証に失敗したというエラーを示します。

$httpStatus = $http_response_header [0];

上記のソースコードで、$httpStatus変数にエラーに関するHTTPステータスコードを代入します。

$http_response_header変数が存在しない場合、HTTPステータスコードを取得できない

$http_response_header変数が存在しない場合、isset()関数はfalseを返します。

この場合は、HTTPステータスコードを取得できません。

$httpStatus = "Variable http_response_header is undefined.";

$httpStatus変数に、「変数http_response_headerは未定義です」という文字列を代入します。

$http_response_header変数が存在しない場合、おそらく、URLが見つからない場合だと思います。
もしもそうなら、HTTPステータスコードは404となります。

HTTP通信エラーに関するエラーメッセージを作成して、HTTPリクエスト例外を通知する

$errorMessage .= "http status:" . $httpStatus;
throw new HttpRequestException ( $errorMessage );

HTTP通信エラーに関するエラーメッセージを作成して、$errorMessage変数に代入します。

HTTPリクエスト例外として、そのエラーメッセージをthrow文で通知します。

商品検索の結果が0件の場合、商品情報は無いとする

if (property_exists ( $responseObject, 'Errors' )) { // $jsonResponse内にerrorが含まれる場合

	// 検索結果0件の場合、ここに来る。正常処理なので、throw new HttpRequestException()しなくて良い。
	// $errorCodeText: string型。例:"NoResults"という文字列が取得された。
	$errorCodeText = $responseObject->{'Errors'} [0]->{'Code'};
	$errorMessage = $responseObject->{'Errors'} [0]->{'Message'};

	// 検索結果0件以外の場合、Eclipseのデバッグでエラー内容を確認すること。
	$responseObject = NULL; // エラー情報を削除した

	// $errorCode=0;
	// throw new HttpRequestException ( $errorMessage, $errorCode );
}

return $responseObject;

PHPオブジェクトの$responseObject変数は、「アマゾン商品の検索結果」を保持します。

この$responseObject変数が「Errorsプロパティ」を持っている場合、
商品検索の結果が0件である、と判断します。

property_exists()関数は、プロパティが、クラスまたはオブジェクトに存在するかどうかを確認します。
プロパティが存在する場合、property_exists()関数はtrueを返します。

商品検索の結果が0件の場合、$responseObject変数の値は以下のようになります。

商品検索の結果が0件の場合、$responseObject->{'Errors'}変数の例。

stdClass Object (
[Errors] => Array (
[0] => stdClass Object 
  (
  [__type] => com.amazon.paapi5#ErrorData 
  [Code] => NoResults 
  [Message] => No results found for your request. 
  ) 
) 
)

エラーコードは、NoResultsです。
結果なし、という意味です。

エラーメッセージは、No results found for your requestです。
ご要望の結果は見つかりませんでした、という意味です。

以上より、「Errorsプロパティ」が$responseObject変数に存在する場合、
商品検索の結果が0件である、と判断しました。

商品検索の結果が0件の場合、エラーではなくて正常処理です。

よって以下のように、
$responseObject変数にNULL値を代入することで、「アマゾン商品の検索結果」は無い、としました。

$responseObject = NULL;

return $responseObject;