PHPとjQueryでデータを抽出

Screenshot_from_2014-10-17 15:54:58allabout48G(仮)にて新しく年齢の範囲からメンバーを抽出する機能を追加しました。
サイトの上部メニュー内「DATA」→ 48グループ年齢分布でチェックできます。(現在公開中止中)アドレスのクエリにadが入ってますが広告のページではありません。またそのせいでadblockが動作して表示されないかも知れません。その場合は、該当ページのみ無効の設定をして下さい。※年齢分布 = age distribution のadです。

最初はHTML5のinputタイプのrangeやjQuery UIのスライダーやらを利用しようかと思っていたわけですが、ひとまずの所ベーシックな方法でajaxを利用することにしてみました。CSS等のデザインあたりはまだ手を付けていません。

単純にフォームを作ってそこから選択すると言う方法だけならPHPでもいいのでしょうが、元々のページ内のカラムがそれぞれにajaxで読み込まれているというのもあり、フォームで送るということは再度読み込みが必要になったりうんぬんと問題もあったわけです。

ajaxは必要な時にPHPにアクセスしてその結果を表示することができます。値だけ抽出できればフォームパーツだけあればデータを送信することができるのはとても便利です。

jQueryがやることは、現在のフォームの値を調べる→その値をPHPに送る→返ってきたデータを表示すると言う感じで、
PHPは、送られた値からデータを抽出して出力すると言うことになります。

PHPで現在のフォームの値が調べられると便利なのですが、フォームパーツを作ることができても、その時々の値は調べることができません。またjQueryで外部ファイルを読み込めてPHPで言う所のforeachのような配列操作が簡単にできればjQueryだけで作成できるのですが、それができないためにどうしても連携になります。

jQueryの中でAKBでいうならメンバーのデータが書いてあるcsvやテキストが用意できればとても良いのですが、そのデータをどうやって取り込むかが最初の問題点になります。jQueryと言うとJSONやJSONP、あるいはxml等でデータを読み込めればよいわけですのでやってできないわけではないのですが、JSONファイルをどうやって作る?と言う点でとても面倒臭い作業になります。

例えばexcelやその他互換のアプリケーション、あるいはGoogleのスプレッドシートでcsvのデータを作るのは誰でもできる作業です。名前と誕生日だけを入力するにしてもAKBのグループ全体の約300人程度なら難なくできなくもない作業です。じゃあ、そこに出身地とGoogle+のIDとブログのRSSアドレス、Twitterを持っていたらTwitterのデータ、所属チーム、グループ、過去のそれらチームやグループ、兼任情報・・・と入れて行ったらあまりにも膨大すぎて凄く大変な作業になります。

ある程度の規模のcsvやデータベースから必要なデータを抽出して、それらを配列でまとめると言うことだけを考えるとPHPはとても優秀だと思います。それらを必要な項目だけ抽出したファイルをtmpファイル等にしてキャッシュすれば無駄なデータを読み出さなくても良くなるので高速にデータ抽出もできる寸法です。

キャッシュファイルを作成する

生のデータファイルをそのまま読み込んでも別に構わないところですが、一定の期間が過ぎたファイルを更新する事でキャッシュファイルを利用する方が高速に読み込めます。更新の時はやや時間がかかるでしょうがキャッシュがある内は高速に表示されるのはとても助かります。
キャッシュを作るのにPearを利用する方法もあります。レンタルサーバーでもpearを利用できる所は利用する方が良いと思います。ただ使えない場合もあるのでその時は自分で作成するためのプログラムを書かないといけません。

考え方として、
※ キャッシュファイル作成についてはちょっと色々とある感じがするので再考して更新します。2014/10/18
※ 一応動作しているもので更新しました。 2014/10/19

こういう感じでしょうか?
まずキャッシュデータのファイルがあるかどうかを確認します(file_exists)。ファイルが存在していたらその更新時間を確認します(filemtime)。
どれぐらいの間隔で更新するかにもよりますがこの場合では1時間経過していれば(strtotime)、fileUpdate関数を呼んでデータを作成・更新します。まだ1時間経っていない場合はファイルを読み込んで配列に格納します。
この時、配列で作っているのはデータを抽出するのに便利だからで、jsonで保存してもxmlで保存してもcsvで保存しても何でも構いません。再度配列に直すよりも最初から配列の方が速いかも知れません。serializeunserializeで若干時間がかかるかも知れませんが国内サーバーならまず体感できないぐらいなのではないでしょうか?
simplexml objectはそのままではシリアライズできないので工夫が必要です。json_encode/decodeで対応してもよいでしょうし、get_object_varsも方法かも知れません。
シリアライズしているのは、配列のまま保存して、それを復元することですぐに利用するためです。

メインの処理 PHP側

ajaxする際に、PHP側ではデータを作成してそれを出力しないといけません。その出力したものがjQueryに返されるわけです。まず入力されてくるデータに間違いがないか必要な値が来ているかどうかをチェックする必要があります。

簡単に言えば $_GETや$_POSTで値を受ければよいのですが、何が飛んでくるかわからないのでひとまずチェックする関数に飛ばします。

今回の「年齢の範囲からメンバーを探す」と言う処理では、グループ名と最年少・最年長の値が必要になります。そのために、

isset($_GET[‘xx’])の部分を&&で結んであるのは、3項目共にきていないと処理しないぜと言う意味です。

飛んできた値を処理する関数の部分は、

こういうのを作ってみました。変な文字列はhtmlエンティティしちゃうぜ(htmlspecialchars)みたいなことをしています。後は、数値が飛んでくるようであれば数値であるかどうか、グループであれば、

こんな感じでチェックすればよいのではないかと思います。後はキャッシュファイルがあればそこから、ない場合は新たに作った配列から必要なデータを抽出して出力します。

おまけ。PHPでプルダウンメニューを作る。

データを送って出力する jQuery側

jQueryでデータを送る前にデータが何であるかをチェックしないといけません。プルダウンメニューの値(optionの値)は、おまけのPHPでプルダウンメニューを作るから引用すれば、

で拾うことができます。これでそれぞれの値を読み込んで、ajaxで送ります。その前にデータを表示するためのブロックを作っておきます。今回はidがshowMemberと言うブロックを作りました。

この中にPHPで出力したデータを表示させます。

.onの後のセレクタ(‘#selectButton’)はこのIDのついてる要素をクリックしたらと言う意味合いです。$.ajaxの中のdata:部分の値はPHPで受ける値($_GET[‘gp’]等)の部分。preventDefaultはreturn falseみたいなものです。意味合いとしては通常行われるアクションをキャンセルするみたいな感じです。セレクタ(‘#selectButton’)がクリックされていない間はずっとfalseなわけです。おまじない的につけています(笑)

さてこのようにして、jQueryからPHPへキーを送り、それを受けたPHPは必要なデータを出力して返します。その返ってきたデータをjQueryが拾って、目的のセレクタの部分に表示させるというわけです。

PHP側で、送られてきた値によって必要な出力を変えれば色々と応用できます。また$.ajaxの部分を関数化して、送るデータをその都度選べるようにしておけば臨機応変に対応できるようになるでしょう。

スポンサーリンク

シェアする

フォローする