前回はPHPによるMySQL操作の基本的なコーディング方法を紹介した。今回は実際に動作するアプリケーションを例に、プログラミングの実践的なテクニックを解説する。
一通りmysql関数を使えるようになったところで、実例を見てみましょう。今回用意したのはWebアドレス帳です。グループでのアドレス管理に対応できるようにWebアプリケーションとして実現してみました。
名前や住所をはじめとする一般的な項目の入力ができ、日付、時間といった文字列以外の特殊な項目の入力にも対応しています。プログラム自体はアドレスの登録・検索・変更・削除といった基本的な機能に絞っていますが、これら1つ1つの機能がデータベースのINSERT・SELECT・UPDATE・DELETEに対応しており、機能ごとのPHPスクリプトの流れが追いやすいのではないかと思います。
機能はシンプルですが、登録項目を変更することで在庫管理などのちょっとした業務アプリケーションにも応用できます。
まずプログラムのインストールです。といってもファイルを展開するだけです。以下のリンクからatmarkit5th.tar.gzをダウンロードしてください。
ダウンロードしたら、Apacheで公開できるディレクトリに展開します。ここでは/usr/local/apache/htdocsを利用します。
# cd /usr/local/apache/htdocs # tar xvfz atmarkit5th.tar.gz
PHPスクリプトのインストールは以上です。特にパーミッションの変更などは必要ありません。
次にデータベースを用意します。第4回でATMARKITデータベースを用意しました。今回も同じデータベースを利用しています。まだ用意していない場合は、データベースのcreate権限を持つユーザー(たいていはrootです)にスイッチしてデータベースを作成します。
# mysqladmin create ATMARKIT
続いてテーブルを作成し、適切な参照権を与えます。ここでは、あらかじめ用意しておいたsqlファイルを利用します。先ほどatmarkit.tar.gzを解凍したatmarkit5thディレクトリに移動します。
# cd atmarkit5th
ここにあるsqlファイルをATMARKITデータベースに流し込みます。
# mysql ATMARKIT < ADDRESS.sql # mysql ATMARKIT < grant.sql
名前からも分かるとおり、ADDRESS.sqlファイルがテーブル“ADDRESS”を作成するためのもの。grant.sqlがADDRESSテーブルの参照権を設定するものです。
以上の作業で下記のようなテーブルが作成されます。
---ADDRESSテーブル----- | no | int(11) | プライマリーキー、番号自動繰り上げ | date | date | 空白不可、キー | time | time | 空白不可 | name | char(40) | | address | char(80) | | tel | char(20) | | email | char(40) | | memo | char(200) | -------------------------
また、第4回と同様、参照権の設定ではlocalhostからの接続も明示的に開けています。
では、アドレス帳プログラムの動作を確認してみましょう。Webブラウザでhttp://127.0.0.1:8080/atmarkit5th/を指定します(PHPスクリプトを展開したディレクトリに合わせてURLも適宜変更してください)。
下のような画面が表示されれば、まずは成功です。あとは適当に「受付処理」や「検索処理」を行い、アドレス帳プログラムが動作しているか確認してみましょう。
処理の流れは図のようになっています。まず受付処理から見ていきましょう。
受付処理(データ登録)では、最初にinsert.phpが呼び出されます。このスクリプトは、変数“$mode”がセットされているか否かで動作が異なります。
if($mode == "insert"){ (中略) } include("insert_form.ini");
$modeに“insert”がセットされていなければ、受付用フォームを表示するためにinsert_form.iniをインクルードします。
受付用フォームもinsert.phpを呼び出しますが、“insert.php?mode=insert”のようにしてURLに変数$modeをセットすることでinsert.phpの動作を変えます。
<FORM ACTION="insert.php?mode=insert" METHOD="POST" ENCTYPE="application/x-www-form-urlencoded">
insert.phpは$modeに“insert”がセットされている場合、下のリストのように各変数の値を指定されたテーブルのカラムに挿入します。
$conn = mysql_connect("127.0.0.1:3306","test","test2001"); mysql_select_db("ATMARKIT"); $date = date ("Y-m-d", mktime ()); $time = date ("H:i:s", mktime ()); $query = "INSERT INTO ADDRESS (date,time,name,address,tel,email,memo) values ('$date','$time','$name','$address','$tel','$email','$memo')";
削除・更新の作業の前には、どのデータを更新するかを選び出す必要があります。検索処理がそれを可能にします。
insert.phpと同様、select.phpも$modeがセットされているか否かで2種類の動作を用意しています。まず指定がなかった場合、select_form.iniをインクルードして検索用のフォームを出力し、このフォームの[検索します]ボタンがクリックされると$modeに“select”をセットしてから再びselect.phpを呼び出します。
$modeに“select”がセットされている場合、フォームの値から検索用のSQL文を生成してデータベース問い合わせを行い、結果を指定された表示数だけ出力します。検索サイトで見かけるように、検索結果の該当範囲を細切れにし、無駄に表示結果を大きくしないようにするため、SELECT文にLIMIT句(データベースTIPS参照)を付けています。もし表示件数が10であれば“limit 0,10”とし、次のページを表示する際には“limit 10,10”にします。[次のx件]がクリックされた際は、SELECTクエリーも一緒に渡すようにしています。次の件数を表示するのなら、各変数を個別に渡すよりも、一度生成したクエリーのLIMIT句だけを変えて渡した方が効率的ですよね。
表示件数を限定したい場合や、「該当の何番目から表示する」といったオフセットもうけたい場合は“LIMIT”句を使います。
SELECT 項目名 FROM テーブル名 WHERE 条件 LIMIT A,B
これで、条件に該当したA番目からB個の結果を返します。“LIMIT 100,20”ならば該当する100件目から20個表示します。該当件数が多くなることが予想される場合はSELECT文にLIMIT句を付け加えると効率的です(MySQLはLIMIT句がある場合、該当分だけ結果が得られるとクエリーを中止します)。
上記の方法は頭から何件、つまり昇順になります。では、ある項目の準に並べて、後から何件目かを表示させたい場合(降順)はどうしたらいいでしょうか。
[解答]
LIMITとORDER BY ... DESCを使います。
SELECT 項目名 FROM テーブル名 WHERE 条件 ORDER BY(項目名) DESC LIMIT A,B
ただし、クエリーまでURLの引数として渡したい場合は少し処理が必要になります。アルファベットだけの検索条件ならいいのですが、漢字や特殊記号も入る場合があります。そのために
$uquery = urlencode($sub_query);
のようにして、URLの引数として渡してもWebブラウザのエラーや変数落ちがないようにします。
また、各フォームの検索条件は完全一致ではなく、部分一致になっています。例えば名前で検索する場合、
WHERE name like '%名前フォームの値%'
を用いています。
検索で意中のデータを見つけて変更したい場合、update.phpを“update.php?no=X”のように番号指定で呼び出します。update.phpは該当のデータをフォーム上に表示します。そのため、dateタイプの値を年・月・日のフォームの形に合うように、事前に定義されたdate2letter()関数を用いて分割します。同様にtimeデータも時・分に分割します(time2letter()関数使用)。
[変更します]がクリックされると、“update.php?update=do”としてupdate.phpを呼び出し、更新を実行します。
最後は削除です。“delete.php?no=X”のように、delete.phpを番号指定で呼び出します。間違って削除処理が実行されるのを防ぐため、JavaScriptを使って簡単な確認を行うようにしています。
<script language="JavaScript1.1"> <!-- function formConfirm( type ) { if (type == "update") { rtn = confirm("データを変更します。\nよろしいですか?"); } else { rtn = confirm("データを削除します。\nよろしいですか?"); } if ( rtn ) { return true; } return false; } //--> </script>
個別の処理以外にも、よく使う関数をまとめたatmarkit.iniファイルがあります。データベースへの接続、SELECT文、UPDATE文、DELETE文の実行といった処理は、ここにまとめてあります。例えば、データベースの初期化処理を呼び出す場合、まずaccess_ADDRESSオブジェクトを作成します。
$am = new access_ADDRESS;
その後メソッドを呼び出します。
$am->db_init();
これらの処理は、atmarkit.iniファイルをインクルードすることで利用可能になっています。
PHPは冒頭でも触れたように、ここ5年で飛躍的に進歩してきたスクリプト言語です。多くの有志の手でさらなる改善が続けられている一方、従来のデータベースとの親和性も大事にされています。
HTML文章に埋め込むスタイルは、いまやJavaでもJSPという形で提供されるなど、多くの言語で実現できるようになってきました。しかし、PDFやGIFの生成をはじめとする各種ライブラリの充実ぶり、cookieでもPOSTでもGETでも変数を簡単に取得できる柔軟さなど、Webアプリケーション構築の優位性はしばらくの間はPHPに分がありそうです。
さて、次回はスクリプト言語の新参者Rubyを取り上げます。日本で生まれたこの言語のMySQLサポートについては、MySQLユーザー会(http://www.mysql.gr.jp/)の大御所とみたまさひろ氏の功労によるところが大きいといえるでしょう。
Copyright © ITmedia, Inc. All Rights Reserved.