URL組み立てるだけなので使ってなかったが、カートを扱いたいのでServices_AmazonECS4を入れました。キャッシュ機能がついているのでキャッシュを使うことにしました。キャッシュ周りはパフォーマンスにすごく影響するのでコードを確認してきました。
キャッシュはAWSのトークンを複数使うよう前提で親切に設計されているようだ。
/**
function _generateCacheId($params)
{
unset($params['AWSAccessKeyId']);
unset($params['AssociateTag']);
$str = '';
foreach ($params as $k => $v) {
$str .= $k . $v;
}
return md5($str);
}AWSのトークンやアソシエイトIDを変更したリクエストでも、以前のキャッシュが使えますよ。ってことだ。親切だ。アソシエイトIDをトラッキングIDにしている場合は便利なんだろう。
ところが、キャッシュIDじゃなくて、キャッシュのコンテンツ保存と取り出し部分を読んでいて問題に気づく。状況に応じてアソシエイトIDを切り替えても、キャッシュ側には反映されない。
// Return cached data if available
$cache_id = false;
if (isset($this->_cache) && !$this->_ignoreCache($params['Operation'])) {
$cache_id = $this->_generateCacheId($params);
$cache = $this->_cache->get($cache_id);
if (!is_null($cache)) {
$this->_processing_time = 0;
return $cache;
}
}
キャッシュのコンテンツをそのままReturnしちゃうので Item->DetailPageURL に埋め込まれたアソシエイトIDがそのままになっちゃう。
_generateCacheIdでAssociateTagをunsetしてる意味がない。
コメントアウトで乗り切ってみる。
/**
function _generateCacheId($params)
{
unset($params['AWSAccessKeyId']);
//unset($params['AssociateTag']);
$str = http_build_query($params);
$str = str_replace("&", "", $str);
$str = str_replace("=", "", $str);
return md5($str);
}
かなり場当たり的に、アソシエイトIDを書き換えるパッチを試してみた。
....
#@989行
if (!is_null($cache)) {
$this->_processing_time = 0;
return $this->afterCache($cache, $this->_associd);
}
....
#@1047行
if ($cache_id) {
$this->_cache->save( $cache_id,
$this->beforeCache($contents, $this->_associd ),
$this->_cache_expire);
}
....
#追記
function beforeCache($data, $AA_TAG){
$str = serialize($data);
$str = str_replace($AA_TAG, "__THIS_IS_AA_TAG_PLACE__", $str);
return $str;
}
function afterCache($str, $AA_TAG){
$str = str_replace("__THIS_IS_AA_TAG_PLACE__",$AA_TAG, $str);
$data = unserialize($str);#ここでエラー
return $data;
}serializeは文字長を変えるとエラーになるので使えなかった。残念。array_walk_recursive()で書き換えるかYAMLにして一括置換しかないかも。PEARのAmazonパッケージをキャッシュして使うとき、アソシエイトIDの切り替えはDetailURLの利用前にGET文字列を書き換えるしかないっぽい。親切なんだか不親切なんだか。よく分かんない。
AmazonECS4をextendsしてパッチClassを作ろうとしたけれど、_sendRequest()メソッドを全てコピー&ペーストで持ってくる必要があるので継承できない。*1キャッシュ&リクエスト&XMLパースがそれぞれ独立した別メソッドであれば簡単にパッチができたのに残念。。
*1:コピペすると親クラスの_sendRequest()が変更される都度パッチ側もコピペにする羽目に。