CodeIgniterの学習 63 - ヤフーの画像検索apiと形態素解析apiを組み合わせてお遊びアプリを作る-その8(現在のコード完成度100%)

CodeIgniterでお遊びアプリを作る8回目。

09/09/28追記
形態素解析結果が取れなくなっている?
取れなくなっているならURL変更だろうな。後で調べる。

apiのURLを最新のものに変更した。

このソースを設置している実験URLは
http://pizw.com/yaimg/
です。

(追記終わり)


09/02/22追記
関連エントリーを追加しました。
http://d.hatena.ne.jp/dix3/20090222/1235252687

実験稼働中のお遊びアプリサイトの説明を書いています。

(追記終わり)




まだいくつか不満は有るけどこれで終わりにする。

今日は、残りの

17.未 検索履歴と接続ログを保存する。
18.未 検索回数のカウンターを設置する。
24.未 ロボットが勝手にカウンターを回さないように、ロボット避けをする。

を済ませる。


完成画面

こんなかんじ。お遊びアプリの割にはよくできましたで賞と褒めておく。
これでムフフな画像を探しまくれる。


ただ直リンク禁止の画像(リファラを見ているブログ等)にはとべないんだよねー。
リファラを詐称して画像取得するzipでくれロジックでも作るしか無いだろうねー。

いつかまたやる気が出たら拡張することにする。


テーブル(DDL)まとめ

今日はこれまでのDDLも全部載せておく。(モデルのソース末尾にも載せてある)

#キャッシュデータ保存用テーブル
CREATE TABLE `yaimg_cache_tbl` (
`id` int(10) unsigned NOT NULL auto_increment,
`cache_key` varchar(64) NOT NULL,  #キャッシュ検索キー 必須
`cache_name` varchar(64) DEFAULT NULL, #キャッシュ名 任意
`cache_data` MEDIUMTEXT  NOT NULL, #キャッシュデータ 必須
`expire_time` varchar(11) DEFAULT NULL,  #有効期限 unixtime 任意
`del_flg` int(1) unsigned DEFAULT 0,
`created` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`modified` timestamp NULL ,
PRIMARY KEY  (`id`),
KEY `idx1_yaimg_cache_tbl` (`id`,`del_flg`),
KEY `idx2_yaimg_cache_tbl` (`cache_key`,`del_flg`),
KEY `idx3_yaimg_cache_tbl` (`expire_time`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;


#検索キーワード履歴(カウンター)保存用テーブル
CREATE TABLE `yaimg_keyword` (
`cache_key` varchar(64) NOT NULL,  #キャッシュ検索キー 必須
`cache_name` varchar(64) DEFAULT NULL, #キャッシュ名 任意
`keyword` TEXT DEFAULT NULL, #キーワード 任意
`url` TEXT DEFAULT NULL, #API接続先のURL
`search_count` int(10) unsigned NOT NULL DEFAULT 1, #検索回数
`del_flg` int(1) unsigned DEFAULT 0,
`created` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`modified` timestamp NULL ,
PRIMARY KEY  (`cache_key`),
KEY `idx1_yaimg_keyword` (`cache_key`,`del_flg`),
KEY `idx2_yaimg_keyword` (`modified`,`del_flg`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;


#総検索回数保存用テーブル
CREATE TABLE `yaimg_counter` (
`id` int(1) unsigned NOT NULL auto_increment,
`cnt` int(10) unsigned NOT NULL DEFAULT 1, #検索回数
`cnt_ptn` varchar(32) NOT NULL , #カウント種別 必須
`del_flg` int(1) unsigned DEFAULT 0,
`created` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`modified` timestamp NULL ,
PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

#接続ログ保存用テーブル
CREATE TABLE `yaimg_access_log` (
`id` int(10) unsigned NOT NULL auto_increment,
`ip_address` varchar(16) DEFAULT '0' NOT NULL, #ipアドレス
`user_agent` varchar(127) NOT NULL , #UA
`log_data` MEDIUMTEXT NULL, #ログデータ用領域 とりあえず何でも保存する
`created` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

前回から増えたのは、

  1. 総検索回数保存用テーブル:yaimg_counter
  2. 接続ログ保存用テーブル:yaimg_access_log

2.の接続ログのログデータはデータをシリアライズしてぶち込む(飽きたので適当)
ログ部分は、もっと丁寧に列を作った方が良いかもね。


コード

全部貼っておく。あと、不要になったソースファイルは削除する。


1:コントローラ… application/controllers/yaimg.php

  • 接続ログの保存
  • 総検索回数の取得

の呼びだしまわりを追加。

<?php if ( !defined( 'BASEPATH' ) ) exit( 'No direct script access allowed' );
/**
 * Yahooの画像検索APIを使ってみるテスト
 */
/**
 *
 * @author : dix3
 * @link http://d.hatena.ne.jp/dix3/
 */

class Yaimg extends Controller {
    // コンストラクタ
    function Yaimg()
    {
        parent :: Controller(); //親のコンストラクタを呼ぶ
        //$this -> load -> helper( array( 'form', 'html', 'text', 'string' ) ); //ヘルパのロード
        $this -> load -> helper( array( 'url','form', 'html', 'text', 'string','date' ) ); //ヘルパのロード
        $this -> load -> library( 'session' ); //セッションライブラリのロード
        $this -> load -> library( 'form_validation' ); //フォームバリデーションライブラリのロード
        $this -> load -> model( 'Mod_yaimg' ); //モデルのロード
    }
    // デフォルトインデックス
    function index( $offset_num = 0 )
    {
        $this -> session -> set_userdata( 'yaimg', array() );
        $this -> page( $offset_num );
    }
    function page( $offset_num = 0 ) // オフセットだけ引数で渡す。キーワードはPOSTデータまたはセッションデータに限定
    {
        $data = array(); //ビュー側に渡す配列
        $data = $this -> Mod_yaimg -> set_init_data(); //画面に固定値のデータをセット
        $data['urchin_tag'] = ( $this -> Mod_yaimg -> get( 'uacct_no' ) ) ? $this -> load -> view( 'urchin_tag', array( 'uacct_no' => $this -> Mod_yaimg -> get( 'uacct_no' ) ) , true ) : '' ; //UACCT_NOをurchinタグのビューに渡す
        $data['result'] = array( 'body' => array(), 'msg' => '', 'page_link' => '', 'sentence' => array() ,'keyword_history' =>array()); //検索結果の初期値

        // バリデーションのルール設定
        $this -> form_validation -> set_rules( 'keyword', $this -> Mod_yaimg -> get( 'input_keyword_value' ), 'trim|required|min_length[2]|max_length[64]|xss_clean' );

        $keyword = $this -> _get_keyword(); //検索キーワードの取得(POST経由又はセッション経由)
        if ( $keyword ) {
            $data['keyword'] = $keyword;
            $this -> session -> set_userdata( 'yaimg', array( 'keyword' => $keyword ) ); //セッションに検索キーワードを保持
            // apiに接続して結果を取得する
            if ( $this -> Mod_yaimg -> query_api( array( 'keyword' => $keyword , 'offset_num' => $offset_num ) ) ) {
                $ir = $this -> Mod_yaimg -> get( 'image_result' );
                $data['result']['body'] = $ir['result']; //結果データ
                $data['result']['page_link'] = $this -> _make_page_link( $ir['attributes'] ); //ページリンクタグの生成
                $data['result']['keyword_history'] = $ir['keyword_history']; //キーワード検索履歴
                $data['result']['msg'] = $this -> _make_info_label( $ir['attributes'] ); //件数情報表示
                if ( $this -> Mod_yaimg -> get( 'parse_api_status' ) ) {
                    $pr = $this -> Mod_yaimg -> get( 'parse_result' ); //形態素解析結果の取得
                    $data['result']['sentence'] = $pr;
                }
            }else {
                $data['result']['msg'] = $this -> Mod_yaimg -> get( 'msg_no_result' );
            }
        }else {
            $this -> session -> set_userdata( 'yaimg', array() );
        }
        $this -> Mod_yaimg -> set_access_log();//接続ログの保存 ログは全て保存
        $data['total_search_count'] = $this -> Mod_yaimg -> get('total_search_count');//総検索回数の取得
        // ビューにデータを渡す
        $this -> load -> view( 'yaimg_index', $data );
    }
    // 検索キーワードの取得
    function _get_keyword()
    {
        $keyword = '';
        // post時とページネーション時の振り分け
        if ( $this -> input -> post( 'submit' ) ) {
            // バリデーション処理の実行
            if ( ( TRUE === $this -> form_validation -> run() ) &&
                    ( $this -> input -> post( 'keyword', true ) !== $this -> Mod_yaimg -> get( 'default_keyword' ) ) ) {
                $keyword = $this -> input -> post( 'keyword', true );
            }
        }else {
            if ( $sess_data = $this -> session -> userdata( 'yaimg' ) ) {
                if ( isset( $sess_data['keyword'] ) ) { // セッションにキーワードがセットされている
                    $keyword = $this -> input -> xss_clean( $sess_data['keyword'] );
                }
            }
        }
        $keyword = reduce_multiples($keyword,' ');//連続した空白の圧縮
        return $keyword;
    }
    // ページリンクタグの生成
    function _make_page_link( $attributes )
    {
        // ページネーションライブラリのロード
        $this -> load -> library( 'pagination' );
        $config['base_url'] = '/yaimg/page/';
        $total_rows = ( int ) $attributes['total'];
        // 件数制限
        $total_rows = ( ( int ) $this -> Mod_yaimg -> get( 'image_api_max_rows' ) <= $total_rows ) ? ( int ) $this -> Mod_yaimg -> get( 'image_api_max_rows' ) : $total_rows;
        $config['total_rows'] = $total_rows ;
        $config['per_page'] = ( int ) $this -> Mod_yaimg -> get( 'image_api_results_count' );
        $config['num_links'] = $this -> Mod_yaimg -> get( 'num_links' );
        $config['first_link'] = $this -> Mod_yaimg -> get( 'first_link' );
        $config['last_link'] = $this -> Mod_yaimg -> get( 'last_link' );
        $config['prev_link'] = $this -> Mod_yaimg -> get( 'prev_link' );
        $config['next_link'] = $this -> Mod_yaimg -> get( 'next_link' );
        $this -> pagination -> initialize( $config );
        return $this -> pagination -> create_links();
    }
    // 件数情報表示
    function _make_info_label( $attributes )
    {
        $ret = '';
        $ilbl = $this -> Mod_yaimg -> get( 'info_label' );
        $total = number_format( $attributes['total'] );
        $position_h = number_format( $attributes['position'] );
        $position_f = number_format( ( int )$attributes['position'] + ( int ) $attributes['count'] -1 ) ;

        $ret = sprintf( $ilbl, $total, $position_h, $position_f ) ; //総件数情報
        if ( ( int )$this -> Mod_yaimg -> get( 'image_api_max_rows' ) <= ( int ) $attributes['total'] ) {
            $ret .= $this -> Mod_yaimg -> get( 'info_label_notice' ); //件数制限のメッセージ
        }
        return $ret;
    }
}

/**
 * End of file yaimg.php
 */
/**
 * Location: ./application/controllers/yaimg.php
 */


 ?>



2:ビュー… application/views/yaimg_index.php

  • 検索キーワード毎の検索回数tips表示(sentence_count_labelのへん)
  • 総検索回数の表示(total_search_count)まわり

を追加。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja">
<head>
<title><?= $svs_title ?></title>
    <?= meta('Content-Type','text/html; charset=utf-8','http-equiv') ?>
    <?= meta('Content-language',$header_lang,'http-equiv') ?>
    <?= meta('Distribution','Global') ?>
    <?= meta('Author','dix3') ?>
    <?= meta('Robots','index,nofollow') ?>
    <?= $header_js ?>
    <?= $header_css ?>
</head>
<body>
    <div>
        <?= heading($svs_description,3) ?>
        <?= form_open('yaimg') ?>
            <?= form_input(array('name'=>'keyword','style'=>'width:250px;','onclick'=>"javascript:this.value='';"),set_value('keyword',$keyword)) ?>
            <?= form_submit('submit',$submit_button_value) ?>
            <?= validation_errors('<div class="error">','</div>'); ?>
            <?php if($result['msg']){ ?><div class='result_msg'><?= $result['msg'] ?></div><?php } ?>
            <?= form_input(array('name'=>'dummy','style'=>'visibility:hidden')) ?>
        <?= form_close() ?>
    </div>
    <hr>
    <div class='sentence_link'>
        <div class='bold'>
        <?php if($result['sentence']){ echo $sentence_link_label; } ?>
        </div>
        <div>
        <?= form_open('yaimg') ?>
        <?php
          $cnt = 0;
          foreach($result['sentence'] as $v){
            echo form_submit('keyword',$v['sentence'],"class=\"keyword\" title=\"{$v['count']}{$sentence_count_label}\"") . "\n";
            $cnt++;
          }
          if($cnt){
            echo form_hidden('submit','submit');
          }
        ?>
        <?= form_close() ?>
        </div>
    </div>
    <?php if($keyword_history_disp == '1'){ ?>
    <div class='sentence_link'>
        <div class='bold'>
        <?php if($result['keyword_history']){ echo '<hr>'.$keyword_history_label; } ?>
        </div>
        <div>
        <?= form_open('yaimg') ?>
        <?php
          $cnt = 0;
          foreach($result['keyword_history'] as $v){
            echo form_submit('keyword',$v['keyword'],"class=\"keyword\" title=\"{$v['search_count']}{$keyword_count_label}\"") . "\n";
            $cnt++;
          }
          if($cnt){
            echo form_hidden('submit','submit');
          }
        ?>
        <?= form_close() ?>
        </div>
    </div>
    <?php } ?>
    <div class='page_link'><?= $result['page_link'] ?></div>
    <div class='result_body'>
     <?php
        foreach($result['body'] as $k => $v){
            $img_tag = img(array('src'=>$v['thumbnail']['url'],
                       'style'=>"width:{$v['thumbnail']['width']};height:{$v['thumbnail']['height']};",
                       'title'=>form_prep($v['summary'].' '.$v['refererurl'].' '.$v['filesize']),
                       'alt'=>form_prep($v['title']),
                       ));
            echo anchor($v['refererurl'],$img_tag,array('target'=>'_blank'))."\n";
        }
     ?>
    </div>
    <div class='page_link'><?= $result['page_link'] ?></div>
    <div class='total_search_count'><?= $total_search_count_label_h.number_format($total_search_count['cnt']).$total_search_count_label_f.date("Y/m/d",mysql_to_unix($total_search_count['created'])) ?></div>
    <hr>
    <?= $api_credit ?>
<?= $urchin_tag ?>
</body>
</html>



3:モデル… application/models/mod_yaimg.php

  • ロボット判定に引っかかったら検索させない(ユーザエージェントクラス使用)
  • 総検索回数の取得
  • 接続ログの保存

処理まわりを追加。

接続ログの保存部分は適当。
POSTデータとかリファラとかをシリアライズして1列にぶち込んでおわり。
ログ解析したいならもっとちゃんと作るべきだが、飽きたのでまあいいや。

<?php if ( !defined( 'BASEPATH' ) ) exit( 'No direct script access allowed' );
/**
 *
 * @author : dix3
 * @link http://d.hatena.ne.jp/dix3/
 */

class Mod_yaimg extends Model {
    var $mod_config;
    var $image_api_arr = array();
    var $parse_api_arr = array();
    var $image_result = array();
    var $parse_result = array();
    var $image_api_status = false;
    var $parse_api_status = false;
    var $sentence = '';
    var $cache_data_arr = array();
    var $search_str = '';
    var $keyword_arr = array();
    // コンストラクタ
    function Mod_yaimg()
    {
        parent :: Model();
        $this -> _init(); //初期化
    }
    // 初期化
    function _init()
    {
        $this -> load -> helper( 'html' );
        // $this -> load -> helper( 'date' );
        $this -> load -> helper( 'yaimg' );
        // $this -> load -> library( 'curl' ); //curlライブラリのロード
        $this->load->library('user_agent');//ユーザエージェントクラスのロード
        $this -> mod_config = $this -> load -> config( 'yaimg_config', true );
    }
    // 画面に固定値のデータをセット
    function set_init_data()
    {
        $arr = array( 'svs_title' ,
            'svs_description' ,
            'header_lang' ,
            'header_js' ,
            'header_css' ,
            'input_keyword_value',
            'keyword' ,
            'submit_button_value' ,
            'sentence_link_label' ,
            'keyword_history_label',
            'api_credit',
            'sentence_count_label',
            'keyword_count_label',
            'keyword_history_disp',
            'total_search_count_label_h',
            'total_search_count_label_f',
            );
        $data = array();
        foreach( $arr as $v ) {
            $data[$v] = $this -> get( $v );
        }
        return $data;
    }
    // 値取得
    function get( $v )
    {
        switch ( $v ) {
            case 'header_js':
                return header_js( $this -> _get_mod_config( $v ) ); //yaimgヘルパのheader_jsタグ
                break;
            case 'header_css':
                return link_tag( $this -> _get_mod_config( $v ) ); //htmlヘルパのlink_tag
                break;
            case 'image_api_arr':
                return $this -> image_api_arr; //画像取得結果の配列
                break;
            case 'parse_api_arr':
                return $this -> parse_api_arr; //形態素解析取得結果の配列
                break;
            case 'image_result':
                return $this -> image_result; //画像取得結果を扱いやすい形に変換した配列
                break;
            case 'parse_result':
                return $this -> parse_result; //形態素解析結果を扱いやすい形に変換した配列
                break;
            case 'image_api_status':
                return $this -> image_api_status; //画像検索結果の取得件数有り真偽
                break;
            case 'parse_api_status':
                return $this -> parse_api_status; // 形態素解析検索結果の取得件数有り真偽
                break;
            case 'sentence':
                return $this -> sentence; // 形態素解析用文字列
                break;
            case 'cache_data_arr':
                return $this -> cache_data_arr; //キャッシュ用データ配列
                break;
            case 'keyword_arr':
                return $this -> keyword_arr; //検索履歴用配列
                break;
            case 'search_str':
                return $this -> search_str;
                break;
            case 'keyword_history':
                return $this -> _get_keyword_history(); //検索履歴の取得
                break;
            case 'total_search_count':
                return $this -> _get_total_search_count(); //総検索回数の取得
                break;
            default:
                return $this -> _get_mod_config( $v ); //configファイルの設定値
                break;
        }
    }
    // configファイルから設定値を読みとる
    function _get_mod_config( $v )
    {
        $v = strtoupper( $v );
        return isset( $this -> mod_config[$v] ) ? $this -> mod_config[$v] : '';
    }
    // 画像取得結果の配列をセット
    function _set_image_api_arr( $arr = array() )
    {
        if ( is_array( $arr ) ) {
            $this -> image_api_arr = $arr;
        }
    }
    // 形態素解析取得結果の配列をセット
    function _set_parse_api_arr( $arr = array() )
    {
        if ( is_array( $arr ) ) {
            $this -> parse_api_arr = $arr;
        }
    }
    // 画像検索結果の戻り値を扱いやすい形に加工してセットする
    function _set_image_result()
    {
        $ret = false;
        $arr = $this -> get( 'image_api_arr' );
        if ( isset( $arr['@attributes'] ) ) {
            $data['attributes']['total'] = $arr['@attributes']['totalresultsavailable'];
            $data['attributes']['count'] = $arr['@attributes']['totalresultsreturned'];
            $data['attributes']['position'] = $arr['@attributes']['firstresultposition'];
            $data['result'] = isset( $arr['result'] ) ? $arr['result'] : array();
            if ( ( int ) $data['attributes']['total'] > 0 ) {
                $this -> _set_sentence(); //形態素解析用文字列のセット
                $this -> _set_image_api_status( TRUE ); //取得件数有り真偽
                $this -> _insert_cache_tbl( 'yaimg_image_api' ); //DBにキャッシュするべき正常なデータがあれば、ここでDBに格納する
                $ret = true;
            }else {
                $this -> _set_image_api_status( FALSE ); //取得件数有り真偽
            }
        }else {
            $data['attributes']['total'] = '';
            $data['attributes']['count'] = '';
            $data['attributes']['position'] = '';
            $data['result'] = array();
            $this -> _set_image_api_status( FALSE ); //取得件数有り真偽
        }
        $data['keyword_history'] = $this -> get( 'keyword_history' ); //検索履歴の取得
        $this -> image_result = $data;
        return $ret;
    }
    // 形態素解析結果の戻り値を扱いやすい形に加工してセットする
    function _set_parse_result()
    {
        $ret = false;
        $arr = $this -> get( 'parse_api_arr' );
        $data = array();
        if ( isset( $arr['uniq_result']['word_list']['word'] ) ) {
            $regexp_ng1 = '#' . $this -> get( 'ng_parse_word1' ) . '#iu';
            $w = str_replace( ',', '|', rtrim( trim( $this -> get( 'ng_parse_word2' ), ',' ) ) ) ;
            $regexp_ng2 = "#^({$w})$#iu";
            foreach( ( array ) $arr['uniq_result']['word_list']['word'] as $v ) {
                if ( !isset( $v['surface'] ) ) {
                    continue;
                }
                if ( mb_strlen( $v['surface'] ) < 2 ) {
                    continue; //1文字単語を除外
                }
                if ( preg_match( $regexp_ng1, $v['surface'] ) ) {
                    continue; //不要な単語を除外
                }
                if ( preg_match( $regexp_ng2, $v['surface'] ) ) {
                    continue; //不要な単語を除外
                }
                $data[] = array( "sentence" => strip_tags( $v['surface'] ), "count" => $v['count'], "pos" => $v['pos'] );
                $ret = true;
            }
            if ( $ret ) {
                $this -> _set_parse_api_status( TRUE ); //取得件数有り真偽
                $this -> _insert_cache_tbl( 'yaimg_parse_api' ); //DBにキャッシュするべき正常なデータであれば、ここでDBに格納する
            }
        }
        $this -> parse_result = $data;
        return $ret;
    }
    // DBにAPI検索結果のキャッシュを保存する
    function _insert_cache_tbl( $cache_name )
    {
        if ( $this -> get( 'cache_use' ) ) {
            $arr = $this -> get( 'cache_data_arr' );
            if ( isset( $arr[$cache_name] ) && is_array( $arr[$cache_name] ) && $arr[$cache_name] ) {
                foreach( $arr[$cache_name] as $data ) {
                    $this -> db -> insert( 'yaimg_cache_tbl', $data );
                }
            }
        }
    }
    // DBに検索履歴を保存する(重複する条件はカウンタと更新日時のみ更新)
    function _insupd_keyword( $cache_name )
    {
        $arr = $this -> get( 'keyword_arr' );
        if ( isset( $arr[$cache_name] ) && is_array( $arr[$cache_name] ) && $arr[$cache_name] ) {
            foreach( $arr[$cache_name] as $data ) {
                $this -> db -> where( 'cache_key', $data['cache_key'] );
                $this -> db -> from( 'yaimg_keyword' );
                // $now = timestamp_to_mysqldatetime(time()); 本当はMY_date_helperを使っているが
                $now = date( "Y-m-d H:i:s", time() );
                if ( $this -> db -> count_all_results() ) {
                    foreach( array( 'cache_name', 'keyword', 'url' ) as $v ) {
                        $this -> db -> set( $v, $data[$v] );
                    }
                    $this -> db -> set( 'search_count', 'search_count+1' , FALSE );
                    $this -> db -> set( 'modified', $now );
                    $this -> db -> where( 'cache_key', $data['cache_key'] );
                    $this -> db -> update( 'yaimg_keyword' );
                }else {
                    foreach( array( 'cache_name', 'keyword', 'url' ) as $v ) {
                        $this -> db -> set( $v, $data[$v] );
                    }
                    $this -> db -> set( 'created', $now );
                    $this -> db -> set( 'modified', $now );
                    $this -> db -> insert( 'yaimg_keyword', $data );
                }
            }
        }
    }
    // 形態素解析用文字列のセット
    function _set_sentence()
    {
        $arr = $this -> get( 'image_api_arr' );
        $s_arr = array();
        // var_dump($arr);
        if ( isset( $arr['result'] ) ) {
            foreach( ( array ) $arr['result'] as $k => $v ) {
                if ( isset( $v['summary'] ) && $v['summary'] ) {
                    $s_arr[] = $v['summary'];
                }
            }
            // var_dump($s_arr);
            $str = implode( ',', $s_arr );
        }
        $this -> sentence = $str;
    }
    // 画像検索結果の取得件数有り真偽をセット
    function _set_image_api_status( $flg )
    {
        $this -> image_api_status = ( $flg ) ? TRUE : FALSE ;
    }
    // 形態素解析検索結果の取得件数有り真偽をセット
    function _set_parse_api_status( $flg )
    {
        $this -> parse_api_status = ( $flg ) ? TRUE : FALSE ;
    }
    // DBにキャッシュデータを保存する予約
    function _set_cache_data_arr( $cache_name , $arr = array() )
    {
        if ( $cache_name && is_array( $arr ) && $arr ) {
            $this -> cache_data_arr[$cache_name][] = $arr; //複数のキャッシュデータを保持する
        }
    }
    // DBに検索履歴データを保存する予約
    function _set_keyword_arr( $cache_name , $arr = array() )
    {
        if ( $cache_name && is_array( $arr ) && $arr ) {
            $this -> keyword_arr[$cache_name][] = $arr; //複数のキャッシュデータを保持する
        }
    }
    // 検索語句
    function _set_search_str( $str )
    {
        $this -> search_str = $str;
    }
    // apiに接続して結果を取得する
    function query_api( $params = array() )
    {
        if($this->agent->is_robot()){
            //ロボット判定に引っかかったら、一切問い合わせをさせずに終わる
            return false;
        }
        $keyword = isset( $params['keyword'] ) ? $this -> input -> xss_clean( strip_tags( $params['keyword'] ) ) : '';
        $offset_num = isset( $params['offset_num'] ) ? $this -> input -> xss_clean( strip_tags( $params['offset_num'] ) ) : '';

        if ( $keyword ) {
            $this -> _query_image_api( $keyword , $offset_num ); //画像検索apiに接続
        }
        $sentence = $this -> get( 'sentence' ); //形態素解析用文字列の取得
        if ( $sentence ) {
            $this -> _query_parse_api( $sentence ); //形態素解析apiに接続
        }
        $this->_update_total_search_count();//総検索回数は常に更新

        return $this -> get( 'image_api_status' ); //画像が見つかったらtrue
    }
    // 画像検索apiに接続して結果を取得する
    function _query_image_api( $keyword = '', $offset_num = 0 )
    {
        if ( !( $url = $this -> _get_ya_url( 'image_api', $keyword , $offset_num ) ) ) {
            return false;
        }

        $data = $this -> _get_contents( 'yaimg_image_api', $url ); //キャッシュまたはURLからデータ取得
        if ( $data ) {
            $obj = @simplexml_load_string( $data ); //xmlのパース
            // 取り回しが面倒なので配列に変換
            $this -> _set_image_api_arr( $this -> _convert_obj_to_arr( $obj ) );
            return $this -> _set_image_result(); // 画像検索結果の戻り値を扱いやすい形に加工してセットする
        }else {
            return false;
        }
    }
    // キャッシュまたはURLからデータ取得
    function _get_contents( $cache_name, $url )
    {
        // キャッシュからデータ取得を試みる
        $cache_key = md5( $cache_name . $url ); //cache_name+urlのmd5を検索キーとする。別にSALTを入れなくてもいいよね
        $ret_data = $this -> _get_contents_by_cache( $cache_name, $cache_key, $url );
        // 適切なキャッシュデータがDB上に無いときは、外部に接続
        if ( !$ret_data ) {
            usleep( 100000 ); //連続してつながないように微妙にウエイト
            // $ret_data = $this -> curl -> get( $url ); //curlライブラリ経由の場合
            $ret_data = @file_get_contents( $url ); // 本当はステータスを取りたいけど
            if ( $ret_data ) {
                // DBにキャッシュデータを保存する予約
                // (正常なデータのみキャッシュさせるのでこの段階ではDBに保存はしない)
                $this -> _set_cache_data_arr( $cache_name,
                    array( 'cache_name' => $cache_name,
                        'cache_key' => $cache_key,
                        'cache_data' => serialize( $ret_data ),
                        'expire_time' => time() + ( int ) $this -> get( 'cache_expire' )
                        )
                    );
            }
        }
        return $ret_data;
    }
    // キャッシュからデータ取得を試みる
    function _get_contents_by_cache( $cache_name, $cache_key, $url )
    {
        $ret_data = NULL;
        if ( !$this -> get( 'cache_use' ) ) {
            return $ret_data;
        }
        // 検索履歴用データのセット
        $this -> _set_keyword_arr( $cache_name, array( 'cache_name' => $cache_name, 'cache_key' => $cache_key, 'url' => $url , 'keyword' => $this -> get( 'search_str' ) ) );
        // 検索履歴の更新
        $this -> _insupd_keyword( $cache_name );
        // -----------------------
        // API接続回数の削減
        // -----------------------
        // APIには接続回数の上限があるため、
        // APIに接続する前に、DB上のキャッシュ用テーブルからレコードを探して外部接続を減らす
        // さらに負荷を減らす為にうまくデータベースキャッシュクラスを使っている
        $this -> db -> where( 'cache_key', $cache_key );
        $this -> db -> where( 'del_flg', 0 );
        $this -> db -> order_by( 'id', 'DESC' );
        $this -> db -> limit( 1 );
        $this -> db -> cache_on(); //データベースキャッシュクラスを併用する
        $query = $this -> db -> get( 'yaimg_cache_tbl' ); //TODO:汎用ライブラリ化して他の処理でも使えるように改良したいがとりあえず
        if ( $query -> num_rows() ) {
            $r = $query -> result_array();
            $id = $r[0]['id'];
            $cache_data = $r[0]['cache_data']; //キャッシュデータ
            $expire_time = $r[0]['expire_time']; //有効期限(unixtime)
            $now = time();
            if ( $now < $expire_time ) { // 有効期限内の場合
                $ret_data = unserialize( $cache_data );
                // var_dump( 'キャッシュ有り' );
            }else {
                // var_dump( '期限切れファイルキャッシュ削除' );
                $this -> _delete_dbcache_by_sql( $this -> db -> last_query() ); //データベースキャッシュの特定のファイルを削除する
                $this -> db -> delete( 'yaimg_cache_tbl', array( 'expire_time < ' => "$now" ) ); //期限切れのレコードを全削除
            }
        }else {
            // レコード0件の時のデータベースキャッシュは次回select時に邪魔になるので削除する
            $this -> _delete_dbcache_by_sql( $this -> db -> last_query() ); //データベースキャッシュの特定のファイルを削除する
            // var_dump( 'レコード0件のファイルキャッシュ削除' );
        }
        $this -> db -> cache_off(); //データベースキャッシュクラスをOFFにする

        return $ret_data;
    }
    // データベースキャッシュクラス使用時のキャッシュファイルの個別削除
    // 本当は DB_cache.phpを拡張したいところが、取りあえずモデル内に設置しておく
    function _delete_dbcache_by_sql( $sql )
    {
        if ( !$this -> db -> cachedir ) {
            // var_dump('application/config/database.phpのcachedirに設定がない');
            return false;
        }
        if ( !realpath( $this -> db -> cachedir ) ) {
            return false;
        }
        if ( !$sql ) {
            return false;
        }
        $segment_one = ( $this -> uri -> segment( 1 ) == FALSE ) ? 'default' : $this -> uri -> segment( 1 );
        $segment_two = ( $this -> uri -> segment( 2 ) == FALSE ) ? 'index' : $this -> uri -> segment( 2 );
        $filepath = $this -> db -> cachedir . '/' . $segment_one . '+' . $segment_two . '/' . md5( $sql ); //DB_cache.phpの仕様
        if ( realpath( $filepath ) ) {
            // var_dump('キャッシュファイルの個別削除実行 path:'.realpath( $filepath ));
            @unlink( realpath( $filepath ) );
            return true;
        }
        return false;
    }
    // 形態素解析apiに接続して単語をばらした結果を配列で取得する
    function _query_parse_api( $sentence = '' )
    {
        if ( !( $url = $this -> _get_ya_url( 'parse_api', $sentence ) ) ) {
            return false;
        }
        $data = $this -> _get_contents( 'yaimg_parse_api', $url ); //キャッシュまたはURLからデータ取得
        if ( $data ) {
            $obj = @simplexml_load_string( $data ); //xmlのパース
            // 取り回しが面倒なので配列に変換
            $this -> _set_parse_api_arr( $this -> _convert_obj_to_arr( $obj ) );
            return $this -> _set_parse_result(); // 形態素解析結果の戻り値を扱いやすい形に加工してセットする
        }else {
            return false;
        }
    }
    // 面倒なのでオブジェクトを再帰的に配列に変換
    function _convert_obj_to_arr( $p )
    {
        if ( is_object( $p ) ) {
            $ret = array();
            $arr = get_object_vars( $p );
            foreach( $arr as $k => $v ) {
                $key = strtolower( $k ); //キーは小文字で統一
                if ( empty( $v ) ) {
                    $ret[$key] = '';
                }else {
                    $ret[$key] = $this -> _convert_obj_to_arr( $v );
                }
            }
        }elseif ( is_array( $p ) ) {
            $ret = array();
            foreach( $p as $k => $v ) {
                $key = strtolower( $k ); //キーは小文字で統一
                if ( empty( $v ) ) {
                    $ret[$key] = '';
                }else {
                    $ret[$key] = $this -> _convert_obj_to_arr( $v );
                }
            }
        }else {
            $ret = $p;
        }
        return $ret;
    }
    // URLの組み立て
    function _get_ya_url( $ptn, $str , $offset_num = 0 )
    {
        if ( !$str ) {
            return '';
        }
        $str = $this -> input -> xss_clean( strip_tags( $str ) );
        $this -> _set_search_str( $str ); //検索履歴保存用
        $appid = $this -> get( 'appid' );
        switch ( $ptn ) {
            case 'parse_api':// 形態素解析用URLの組み立て
                // アルファベットと数字のみの文字列をあらかじめ除外
                $str = preg_replace( '#[a-zA-Z0-9]+#iu', ' ', $str );
                $enc_str = urlencode( mb_substr( $str , 0, 960 ) ); //適当に短くしないとリクエストが長すぎて蹴られる
                $url = $this -> get( 'parse_api_url' );
                $url = str_replace( '%appid%', $appid, $url );
                $url = str_replace( '%sentence%', $enc_str, $url );
                return $url;
                break;
            case 'image_api':// 画像検索用URLの組み立て
                $enc_str = urlencode( $str );
                $url = $this -> get( 'image_api_url' );
                $url = str_replace( '%appid%', $appid, $url );
                $url = str_replace( '%keyword%', $enc_str, $url );
                $site_lock_url_list = $this -> get( 'site_lock_url_list' ); //検索対象のURLを限定
                if ( $site_lock_url_list ) {
                    $s_arr = explode( ',', trim( str_replace( ' ', '', $site_lock_url_list ) ) );
                    $image_api_site_lock_url = '&site=' . implode( '&site=', $s_arr );
                    $url = str_replace( '%image_api_site_lock_url%', $image_api_site_lock_url, $url );
                }
                $arr = array( 'image_api_adult_ok',
                    'image_api_similar_ok',
                    'image_api_language',
                    'image_api_country',
                    'image_api_results_count',
                    );
                foreach( $arr as $v ) {
                    $url = str_replace( "%{$v}%", $this -> get( $v ), $url );
                }
                // 取得開始カウントは正の整数のみ
                if ( !preg_match( '#^\d+$#', $offset_num ) || ( ( int ) $offset_num < 1 ) ) {
                    $start_num = ( int ) $this -> get( 'image_api_start_num' );
                }else {
                    $start_num = ( int ) $offset_num; //パラメータstartの調整
                }
                $url = str_replace( "%image_api_startcount_num%", $start_num, $url );
                // echo($url);
                return $url;
                break;
            default:
                return '';
                break;
        }
    }
    // 検索履歴の取得
    function _get_keyword_history( $num = 0 )
    {
        if(!$this->get('keyword_history_disp')){
            return array();
        }
        if(0 == $num){
            $num = (int) $this->get('keyword_history_count');
        }
        $ret_arr = array();
        $this -> db -> select( 'keyword');
        $this -> db -> select( 'sum(search_count) as search_count');//遅いかなー
        $this -> db -> where( 'del_flg', 0 );
        $this -> db -> where( 'cache_name', 'yaimg_image_api' );
        $this -> db -> group_by( 'keyword' );//遅いかなー
        $this -> db -> order_by( 'modified', 'DESC' );
        $this -> db -> limit( ( int ) $num );
        $query = $this -> db -> get( 'yaimg_keyword' );
        if ( $query -> num_rows() ) {
            $ret_arr = $query -> result_array();
        }
        return $ret_arr;
    }
    //総検索回数の取得
    function _get_total_search_count()
    {
        $this -> db -> select('cnt');
        $this -> db -> select('created');
        $this -> db -> where('cnt_ptn','total');
        $this -> db -> limit( 1 );
        $query = $this -> db -> get( 'yaimg_counter' );
        if ( $query -> num_rows() ) {
            $arr = $query -> result_array();
            return $arr[0];
        }else{
            //初期マスタのインサート
            $now = date( "Y-m-d H:i:s" , time());
            $this -> db -> set( 'cnt_ptn', 'total');
            $this -> db -> set( 'created', $now  );
            $this -> db -> set( 'modified', $now  );
            $this -> db -> where('cnt_ptn','total');
            $this -> db -> insert( 'yaimg_counter' );
        }
    }
    //総検索回数の更新
    function _update_total_search_count()
    {
        $this -> db -> set( 'cnt', 'cnt+1' , FALSE );
        $this -> db -> set( 'modified', date( "Y-m-d H:i:s" , time()) );
        $this -> db -> where('cnt_ptn','total');
        $this -> db -> update( 'yaimg_counter' );
    }
    //接続ログの保存 ログはいろいろ保存
    function set_access_log(){
        $log_data = array();//ログデータはとりあえずシリアライズしてぶち込む。手抜き
        $log_data['post'] = $_POST;//素のPOSTデータをそのまま保存
        $log_data['is_robot'] = $this->agent->is_robot();//ロボットかどうか
        $log_data['is_browser'] = $this->agent->is_browser();//ブラウザが既知かどうか
        $log_data['platform'] = $this->agent->platform();//プラットフォーム
        $log_data['referrer'] = $this->agent->is_referral() ? $this->agent->referrer() : NULL ;//リファラ
        $this -> db -> set( 'ip_address', $this->input->ip_address());
        $this -> db -> set( 'user_agent', substr($this->input->user_agent(), 0, 127));
        $this -> db -> set( 'log_data', serialize($log_data));
        $this -> db -> set( 'created', date( "Y-m-d H:i:s" , time()) );
        $this -> db -> insert( 'yaimg_access_log');
    }
} //endofclass
// yaimg_cache_tblのddl
/**
 * #キャッシュデータ保存用テーブル
 * CREATE TABLE `yaimg_cache_tbl` (
 * `id` int(10) unsigned NOT NULL auto_increment,
 * `cache_key` varchar(64) NOT NULL,  #キャッシュ検索キー 必須
 * `cache_name` varchar(64) DEFAULT NULL, #キャッシュ名 任意
 * `cache_data` MEDIUMTEXT  NOT NULL, #キャッシュデータ 必須
 * `expire_time` varchar(11) DEFAULT NULL,  #有効期限 unixtime 任意
 * `del_flg` int(1) unsigned DEFAULT 0,
 * `created` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
 * `modified` timestamp NULL ,
 * PRIMARY KEY  (`id`),
 * KEY `idx1_yaimg_cache_tbl` (`id`,`del_flg`),
 * KEY `idx2_yaimg_cache_tbl` (`cache_key`,`del_flg`),
 * KEY `idx3_yaimg_cache_tbl` (`expire_time`)
 * ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 *
 *
 * #検索キーワード履歴(カウンター)保存用テーブル
 * CREATE TABLE `yaimg_keyword` (
 * `cache_key` varchar(64) NOT NULL,  #キャッシュ検索キー 必須
 * `cache_name` varchar(64) DEFAULT NULL, #キャッシュ名 任意
 * `keyword` TEXT DEFAULT NULL, #キーワード 任意
 * `url` TEXT DEFAULT NULL, #API接続先のURL
 * `search_count` int(10) unsigned NOT NULL DEFAULT 1, #検索回数
 * `del_flg` int(1) unsigned DEFAULT 0,
 * `created` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
 * `modified` timestamp NULL ,
 * PRIMARY KEY  (`cache_key`),
 * KEY `idx1_yaimg_keyword` (`cache_key`,`del_flg`),
 * KEY `idx2_yaimg_keyword` (`modified`,`del_flg`)
 * ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 *
 *
 * #総検索回数保存用テーブル
 * CREATE TABLE `yaimg_counter` (
 * `id` int(1) unsigned NOT NULL auto_increment,
 * `cnt` int(10) unsigned NOT NULL DEFAULT 1, #検索回数
 * `cnt_ptn` varchar(32) NOT NULL , #カウント種別 必須
 * `del_flg` int(1) unsigned DEFAULT 0,
 * `created` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
 * `modified` timestamp NULL ,
 * PRIMARY KEY  (`id`)
 * ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 *
 *
 * #接続ログ保存用テーブル
 * CREATE TABLE `yaimg_access_log` (
 * `id` int(10) unsigned NOT NULL auto_increment,
 * `ip_address` varchar(16) DEFAULT '0' NOT NULL, #ipアドレス
 * `user_agent` varchar(127) NOT NULL , #UA
 * `log_data` MEDIUMTEXT NULL, #ログデータ用領域 とりあえず何でも保存する
 * `created` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
 * PRIMARY KEY  (`id`)
 * ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 *
 */

/**
 * End of file mod_yaimg.php
 */
/**
 * Location: ./application/models/mod_yaimg.php
 */

 ?>



4:ライブラリ… application/libraries/lib_yaimg.php

結局ライブラリを作らなかったので、ファイル丸ごと削除


5:ヘルパー… application/helpers/yaimg_helper.php

前回までと変わらず。ヘッダのjavascriptを読みこむ用。

<?php if ( !defined( 'BASEPATH' ) ) exit( 'No direct script access allowed' );
/*
* @author: dix3
* @link : http://d.hatena.ne.jp/dix3/
*/
if ( ! function_exists( 'header_js' ) ) {
    // scriptの読み込みタグ生成
    // 例: header_js('js/hogehoge.js');で
    // <script src="js/hogehoge.js" type="text/javascript"></script>
    // を作る
    function header_js( $src_str = '', $charset = '' )
    {
        $ret = '';
        if ( $src_str ) {
            if ( $charset ) {
                $cstr = ' charset="' . $charset . '" ' ;
            }else {
                $cstr = '' ;
            }
            $ret .= '<script language="javascript" type="text/javascript" src="' . $src_str . '"' . $cstr . "></script>\n";
        }
        return $ret;
    }
}

/* End of file yaimg_helper.php */
/* Location: ./application/helpers/yaimg_helper.php */

 ?>



6:設定ファイル… application/config/yaimg.php

  • SENTENCE_COUNT_LABEL
  • KEYWORD_COUNT_LABEL
  • KEYWORD_HISTORY_COUNT
  • KEYWORD_HISTORY_DISP
  • TOTAL_SEARCH_COUNT_LABEL_H
  • TOTAL_SEARCH_COUNT_LABEL_F
  • CACHE_USE

とかを追加。

あと、
HEADER_JSを空にした。
HEADER_CSS部分のCSSのパスは、環境に合わせて各自変えてください。


APPIDは各自がヤフーから取得してね。
APIの仕様はここらへん http://developer.yahoo.co.jp/

<?php if ( ! defined( 'BASEPATH' ) ) exit( 'No direct script access allowed' );
/**
 *
 * @author : dix3
 * @link : http://d.hatena.ne.jp/dix3/
 */

$config['SVS_TITLE'] = 'ヤフー画像検索 WEBAPIテスト'; //タイトル
$config['SVS_NAME'] = 'yaimg_search'; //サービス名
$config['SVS_DESCRIPTION'] = 'ヤフー画像検索と形態素解析の実験'; //ページタイトル
$config['HEADER_LANG'] = 'ja'; //Content-language
$config['HEADER_JS'] = ''; //javascriptの相対パス
$config['HEADER_CSS'] = 'css/yaimg.css'; //cssの相対パス
$config['INPUT_KEYWORD_VALUE'] = 'キーワード'; //キーワード欄の名称
$config['SUBMIT_BUTTON_VALUE'] = 'ぽちっとな!画像検索'; //サブミットボタン名
$config['KEYWORD'] = ''; //キーワード欄のデフォルト値
$config['SENTENCE_LINK_LABEL'] = '関連キーワード:';
$config['KEYWORD_HISTORY_LABEL'] = 'みんなの最新検索キーワード:';
$config['INFO_LABEL'] = '総件数:%s件 %s件目 〜 %s件目を表示'; //情報用ラベル
$config['INFO_LABEL_NOTICE'] = ' (検索結果の表示は999件が上限です。)'; //情報用ラベル
$config['FIRST_LINK'] = '最初のページ'; //ページネーション用
$config['LAST_LINK'] = '最後のページ'; //ページネーション用
$config['PREV_LINK'] = '&lt;前へ '; //ページネーション用
$config['NEXT_LINK'] = '&gt;次へ'; //ページネーション用
$config['NUM_LINKS'] = '5'; //ページネーション用
$config['SENTENCE_COUNT_LABEL'] = '';//title用
$config['KEYWORD_COUNT_LABEL'] = '回検索';//title用
$config['KEYWORD_HISTORY_COUNT'] = '50';//検索履歴の表示件数
$config['KEYWORD_HISTORY_DISP'] = '1' ;//みんなの検索履歴の表示:1 非表示:0 非表示でもカウント数の記録は行う
$config['TOTAL_SEARCH_COUNT_LABEL_H'] = '総検索回数:' ;//カウンターのラベル
$config['TOTAL_SEARCH_COUNT_LABEL_F'] = '回 / カウント開始: ' ;//カウンターのラベル
$config['CACHE_USE'] = '1' ;//API負荷削減のためにキャッシュ機能(DB内にキャッシュ保存+ファイルキャッシュ併用)を使うか 使用:1 不使用:0
$config['CACHE_EXPIRE'] = '43200';//同じ検索内容のキャッシュ有効期間(43200秒すなわち12時間)
$config['API_CREDIT'] = "<!-- Begin Yahoo! JAPAN Web Services Attribution Snippet -->\n<a href=\"http://developer.yahoo.co.jp/about\">\n<img src=\"http://i.yimg.jp/images/yjdn/yjdn_attbtn2_105_17.gif\" width=\"105\" height=\"17\" title=\"Webサービス by Yahoo! JAPAN\" alt=\"Webサービス by Yahoo! JAPAN\" border=\"0\" style=\"margin:15px 15px 15px 15px\"></a>\n<!-- End Yahoo! JAPAN Web Services Attribution Snippet -->\n";//クレジット表記
$config['UACCT_NO'] = ''; //google-analyticsのurchinのタグ
// yahooのアプリケーションID appid(自分で取得する)
$config['APPID'] = ''; //yahooのappid(自分でとる)
// API接続URLのテンプレート
// yahooの形態素解析apiのURL
#$config['PARSE_API_URL'] = 'http://api.jlp.yahoo.co.jp/MAService/V1/parse?appid=%appid%&results=uniq&uniq_filter=9&sentence=%sentence%';
$config['PARSE_API_URL'] = 'http://jlp.yahooapis.jp/MAService/V1/parse?appid=%appid%&results=uniq&uniq_filter=9&sentence=%sentence%';
// yahooの画像検索apiのURL
#$config['IMAGE_API_URL'] = 'http://api.search.yahoo.co.jp/ImageSearchService/V1/imageSearch?appid=%appid%&query=%keyword%&adult_ok=%image_api_adult_ok%&similar_ok=%image_api_similar_ok%&language=%image_api_language%&country=%image_api_country%%image_api_site_lock_url%&results=%image_api_results_count%&start=%image_api_startcount_num%';
$config['IMAGE_API_URL'] = 'http://search.yahooapis.jp/ImageSearchService/V1/imageSearch?appid=%appid%&query=%keyword%&adult_ok=%image_api_adult_ok%&similar_ok=%image_api_similar_ok%&language=%image_api_language%&country=%image_api_country%%image_api_site_lock_url%&results=%image_api_results_count%&start=%image_api_startcount_num%';

// 画像検索APIのパラメータ
$config['IMAGE_API_ADULT_OK'] = '1'; //アダルト OK:1,NG:0
$config['IMAGE_API_SIMILAR_OK'] = '1'; //SIMILAR OK:1,NG:0
$config['IMAGE_API_LANGUAGE'] = 'ja'; //言語 ja
$config['IMAGE_API_COUNTRY'] = 'ja'; //国 ja
$config['IMAGE_API_RESULTS_COUNT'] = '50'; //一回の問い合わせのデータ取得件数
$config['IMAGE_API_START_NUM'] = '1'; //検索結果のn番目から表示
$config['IMAGE_API_MAX_ROWS'] = '1000'; //1000件を超えられないAPIの仕様
$config['SITE_LOCK_URL_LIST'] = ''; //画像検索を特定のサイト内に限定するときに指定
// $config['SITE_LOCK_URL_LIST'] = 'hatena.ne.jp,example.com';//画像検索を特定のサイト内に限定するときに指定。カンマ区切りで複数指定可
// 形態素解析での抽出対象外ワード、正規表現で指定
$config['NG_PARSE_WORD1'] = '[-+_0-9a-zA-Z\s0123456789]+';//数字のみアルファベットのみを除外
// 形態素解析での抽出対象外ワード、カンマ区切りで指定
$config['NG_PARSE_WORD2'] = '上記,名前,名無し,投稿,片手,クリック,サイト,ジャンプ,リンク,これ,それ,あれ,こと,どれ,ここ,そこ,こちら,先週,今週,来週,版,先月,今月,来月';
// 合致したデータが無いときのメッセージ
$config['MSG_NO_RESULT'] = '該当するデータは見つかりませんでした。';
/**
 * End of file yaimg.php
 */
/**
 * Location: ./application/config/yaimg.php
 */

 ?>


7:javascriptファイル… ドキュメントルート/js/yaimg.js

結局使わなかったので、ファイル丸ごと削除


8:cssファイル… ドキュメントルート/css/yaimg.css

total_search_countを追加

/* author : dix3 */
/* link : http://d.hatena.ne.jp/dix3/ */

body{ 
 color:#fff;
 background:#111;
}
hr { 
 color:#eeeeee;
 height:1px; 
}
h1,h2,h3{
 font-size:1em;
}
a{ 
  text-decoration: none;
}

.error{
 background:#ff0000;
 color:#fff;
 padding:3px;
 font-weight:bold;
 display:inline;
}
.result_msg{
 background:#ffd700;
 color:#111;
 padding:3px;
 font-weight:bold;
 display:inline;
}

.result_body{
 text-decoration: none; 
 margin:20px 0 0 0;
 padding:5px; 
}
.result_body a:link,
.result_body a:visited,
.result_body a:active{
  color: #111;
}
.result_body a:hover{
  color: #ffd700;
}

.page_link{
 font-size:1.2em;
 text-align:center;
 margin:10px 0 10px 0;
}

.page_link b{
 color:#111;
 background:#ffd700;
}
.page_link a{
 color:#fff;
}

.page_link a:hover{
 color:#ffd700;
}

.sentence_link input.keyword{
 margin:0px;
 padding:0px;
 color:#fff;
 background:#111;
 font-size:0.875em;
 border:0;
 cursor:pointer;
}

.sentence_link input.keyword:hover{
 color:#ffd700;
 background:#777;
}

.bold{
 font-weight:bold;
}
.total_search_count{
 text-align:right;
 font-size:12px;
}

img{
 border:2px solid #111;
}
img:hover{
 border:2px solid #ffd700;
}


9:google-analytics(urchin)用ビューファイル… application/modules/yaimg/views/urchin_tag.php

前回までと変わらず。

<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
var pageTracker = _gat._getTracker("<?= $uacct_no ?>");
pageTracker._trackPageview();
</script>




こんな感じ。以上。


あとはいろいろいじってみてくださいな。


雑記

お勧めは、設定ファイルの

$config['SITE_LOCK_URL_LIST'] = ''; //画像検索を特定のサイト内に限定するときに指定

を、

$config['SITE_LOCK_URL_LIST'] = 'hatena.ne.jp,livedoor.jp'; //画像検索を特定のサイト内に限定するときに指定

みたいに、画像の検索対象を特定のサイト限定にして画像検索アプリとすること。


ついでにgoogle-analyticsでUACCT_NOを取得して、$config['UACCT_NO'] にセットしておけば、
アクセス解析google君に任せられる。($_GETを使っていないからあまり解析にはならないかもしれないけど)



あとは、viewとcssを格好良く改造して、
お気に入りのサイト限定の画像連想検索サービスのできあがり。




極力環境に依存しない・他にも影響させないように、処理を書いているつもりだけど、
もし動かなかったら、頑張って改造してください。

環境云々や仕様等は一連のエントリーをその1から見てください。



09/02/22 一部修正

  • ヘルパのロードに 'url','date'を追加(autoloadで読みこんでいたため)
  • cssに img , img : hover 追加

09/08/07 一部修正

  • ビューにform_input(array('name'=>'dummy','style'=>'visibility:hidden')) を追加(Enterキーの挙動調整用)
  • $config['KEYWORD'] の初期値を空にした。