前回cakephpで作ったシンプルなamazon検索ページをちょっと改良。
セキュリティ的なことがまだ考慮できてないのでデモページは公開せず。
勉強用の参考資料としてソースのみ公開。
今回の改良で、
cakeデイレクトリ/amazon/search/キーワード(日本語の場合はURLエンコード)
というアドレスで検索結果が表示されるようになった。これで直接検索結果にリンクを貼れる。
amazon_controller.php
<?php
class Amazon_Info {
const ACCECSS_KEY_ID = '自分のamazonwebserviceのアクセスキー';
// アフィリエイトIDを使いたい場合に指定
const ASSOC_ID = '自分のアフィリエイトID';
}
require_once 'Services/AmazonECS4.php';
class AmazonController extends AppController {
var $name = 'Amazon';
var $uses = array();
var $helpers = array('Html', 'Form');
function index()
{
if(empty($this->data)) {
$this->render();
} else {
$this->redirect('/amazon/search/'. $this->data['Amazon']['words']);
}
}
function search($words = null)
{
if(empty($words)){
$this->render("index");
} else {
$amazon = new Services_AmazonECS4(
Amazon_Info::ACCECSS_KEY_ID,
Amazon_Info::ASSOC_ID
);
$result = $amazon->setLocale('JP');
$options['Keywords'] = $words;
$options['ResponseGroup'] = 'Medium';
$result = $amazon->ItemSearch('Books', $options);
$this->set('words', $words);
$this->set('result', $result);
$this->render();
}
}
}
?>
index.thtml
<form action="<?php echo $html->url('/amazon'); ?>"
method="post">
<?php echo $html->input('Amazon/words'); ?>
<?php echo $html->submit('search');?>
</form>
search.thtml
<form action="<?php echo $html->url('/amazon'); ?>" method="post">
<?php echo $html->input('Amazon/words', array('value'=>$words)); ?>
<?php echo $html->submit('search');?>
</form>
<?php
foreach ($result['Item'] as $item) {
displayOne($item); // 一件分の表示
}
/** 一件分の結果を表示する関数 */
function displayOne($item) {
$attributes = $item['ItemAttributes'];
// HTMLで表示して問題の無い形式にエスケープ
$title = htmlspecialchars(
$attributes['Title'], ENT_QUOTES);
if (isset($attributes['Author'])) {
$author = htmlspecialchars(
// 複数著者はカンマでまとめる
implode(',', $attributes['Author']),
ENT_QUOTES);
} else {
$author = '(著者無し)';
}
$detailUrl = htmlspecialchars(
$item['DetailPageURL'], ENT_QUOTES);
$imageUrl = htmlspecialchars(
$item['MediumImage']['URL'], ENT_QUOTES);
$formattedPrice = htmlspecialchars(
$attributes['ListPrice']['FormattedPrice'], ENT_QUOTES);
$asin = htmlspecialchars(
$item['ASIN'], ENT_QUOTES);
$salesRank = (integer)($item['SalesRank']);
// 整形して表示
echo "<h3>タイトル: ${title}</h3>";
echo "<a href=\"${detailUrl}\">";
echo "<img src=\"${imageUrl}\" />";
echo "</a>";
echo "<dl>";
echo "<dt>著者</dt><dd>${author}</dd>";
echo "<dt>価格</dt><dd>$formattedPrice</dd>";
echo "<dt>ASIN</dt><dd>$asin</dd>";
echo "<dt>売り上げランク</dt><dd>${salesRank}位</dd>";
echo "</dl>";
}
?>
残りの問題
・POSTデータの入力値チェックがされていない(たぶん。cakephp側でなんらかのチェックが自動でなされているのかどうか調査の必要あり)。
・エラー発生時の処理を記述してない。
・なぜか表示が崩れる?
・商品イメージや売上ランク等の情報が取得できなかった場合の処理が必要そう。
・キャッシュ機能が実装されていない。