木曜日, 2月 22, 2007

cakephpでwebサービスapiを活用したサンプルサイトを作ってみる3

とりあえず極力シンプルにamazon検索機能のあるページをcakephpで作成。

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 {
            $words = $this->data['Amazon']['words'];
            
            $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('result', $result);
            $this->render("search");
        } 
    }
}
?>

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'); ?>
        <?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側でなんらかのチェックが自動でなされているのかどうか調査の必要あり)。
・エラー発生時の処理を記述してない。

・なぜか表示が崩れる?
・商品イメージや売上ランク等の情報が取得できなかった場合の処理が必要そう。
・GETクエリではないので直接リンクを貼ったりできない。

・キャッシュ機能が実装されていない。

とりあえずこれを土台にコードの改善を試みてみる。

0 件のコメント: