連載第2回目は、PHPの基礎と「簡易オンラインストア」の概要について説明しました。今回はPHPのサンプルコードを実際に見ながら、フォームデータの受け渡し方法について理解を深めましょう。
今回は、以下の2通りの方法を紹介します。
関連リンク:
連載 快速MySQLでデータベースアプリ!
http://www.atmarkit.co.jp/flinux/index/indexfiles/mysqlindex.html
連載 今から始める MySQL入門
http://www.atmarkit.co.jp/flinux/index/indexfiles/mysql5index.html
フォーム中に値を埋め込む方法(1)
サンプルのダウンロードと実行
まず、フォーム中に値を埋め込んでデータの受け渡しをする方法です。sample1のソースファイルをダウンロードして、Apacheのドキュメントルートに展開してみましょう。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
展開後、ブラウザで「http://サーバ/sample1/menu.php」にアクセスすると実際に動作を確認できます(画面1)。
解説
sample1では、前回紹介した共通処理で要求されている事項をPHPで実現しています。
- メニュー画面(menu.php)
- カウントデータにファイル「/tmp/count.dat」を使用
- 注文番号をフォームに埋め込む際に <input type"hidden"...>タグを使用
- 確認画面(confirm.php)
- 注文番号を$_POST["order_id"]で取得。注文番号がセットされていなければ強制終了
- 選択された各アイテムの個数を$_POST[ "apache"]、$_POST["qmail"]、$_POST["mysql"]、$_POST["bind"]で取得
- 入力された受注データをフォームに埋め込む際、 <input type"hidden"...>タグを使用
- 完了画面(purchase.php)
- 注文番号を$_POST["order_id"]で取得。注文番号がセットされていなければ強制終了
- 選択された各アイテムの個数を$_POST[ "apache"]、$_POST["qmail"]、$_POST["mysql"]、$_POST["bind"]で取得。また、氏名と住所をそれぞれ$_POST["name"]、$_POST["address"]で取得
- 受注データを「/tmp/order注文番号.txt」(注文番号が1000000001なら/tmp/order1000000001.txt)に書き出す
メニュー画面(menu.php)
以下、sample1の「メニュー画面(menu.php)」でポイントとなる個所を解説します。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
1〜16行目で、カウントデータファイル「/tmp/count.dat」から注文番号を読み込みます。
3〜9行目
「file_exists("/..pathto../ファイル名")」で指定されたファイルの有無を確認し(3行目)、ファイルがなければ、カウントデータの初期値として「1000000001」を使用します(8行目)。
条件分岐に「if文」を使用します。ファイルを開く際には「fopen("/..pathto../ファイル名", "読み込みモード")」でファイルポインタを取得します(4、7行目)。読み込みモード「r+」では読み込みと書き出し用に、「w」で書き出し専用にファイルを開きます。ファイルパスの指定が間違っていたり、ファイルの書き込みや読み込み権限が正しくなかったりなどの理由で、ファイルを開くことができない場合には「die("メッセージ")」で処理を中断しメッセージを表示します。
カウントデータファイルが存在した場合には、「fgets($ファイルポインタ)」でカウント値を読み込み、その値に1を加え注文番号を生成します(5行目)。fgets()は指定したファイルの1行を取り出して文字列として返します。また、引数で最大読み込みバイト数を指定する必要がありますが、省略した場合には自動的に1024bytesが適用されます。1行が長い場合には注意が必要です。注文番号は注文の成立/不成立にかかわらず、単純に注文ごとに1ずつカウントアップします。
10行目
「set_file_buffer("ファイルポインタ", 0)」で書き込みバッファを使用しないようにします。書き込みバッファはOSがメモリ上に用意する一時的な記憶領域です。ハードディスクなど物理的なファイルシステムに書き出す前に利用されます。
バッファを利用することで、書き込みパフォーマンスを上げることができる一方、極めて短時間ですが、バッファ上のデータとファイルシステム上のデータに差異が発生します。その差異が発生している瞬間に障害が起きた場合、データが消失する可能性があります。そのため、バッファを利用せずに直接ファイルシステムに書き込むようにします。
11行目
「flock($ファイルポインタ, LOCK_EX)」でファイルをロックし、ほかの処理でファイルが更新されないよう「排他制御」を行います。今回のサンプルでは同時に多くのユーザーがアクセスすることはまれですが、一般的なオンラインシステムでは同時処理に対するデータの矛盾が発生しないよう留意する必要があります。
12〜15行目
「rewind($ファイルポインタ)」でファイルポインタの位置を先頭に戻します(12行目)。データの書き込みには「fputs($ファイルポインタ, "書き出す内容")」を利用します(13行目)。データの書き込みが完了後、ファイルロックを解除して(14行目)ファイルポインタを解放します(15行目)。
ちなみに、PHP5では文字列のファイルへの書き出しfopen()、fputs()、fclose()を「file_put_contents()」で、ファイルの内容を文字列として読み込むfopen()、fgets()、fclose()を「file_get_contents()」で実現できます。これら2つの関数は、特に一度にファイル全体を取り扱う(読み込み、書き込み)ときに便利です。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
48行目
フォームデータに注文番号を埋め込むため、<input type="hidden"...>を利用します。
通常のブラウザ表示では値を見ることはできませんが、Internet Explorerの「ソースの表示」などで簡単に見ることができます。注文番号をHTML中に書き出すには、1行スクリプトを用いて「print $order_no」を利用します。
Copyright © ITmedia, Inc. All Rights Reserved.