最近、PHP/FI (http://www.vex.net/php/) という CGI ツールが人気を集めています。PHP/FI は、perl に似た一種のス クリプト言語で、条件文、制御構造、関数、ローカル変数などの機能を持って います。最も重要な特徴は、apache (http://www.apache.org/) という httpd サーバと組み合わせた時に、httpd サーバと同じプロセス空間 で実行することができるという点です(つまり、外部プロセスではなく、関数 として実行される)。CGI プロセスを起動するオーバーヘッドがないため、劇 的に性能が改善されます。
次に、HTML ファイルの拡張子を ``phtml'' とすることにより、CGI であること を意識することなく、通常の HTML ファイルと同様に扱うことができます。こ の場合、httpd サーバは 自動的にphtml 拡張子の付いた HTML ファイルを PHP/FI のパーサに渡し、その結果がクライアントに渡されます。これは ``CGI redirection'' という機能ですが、apache の他に、NSCSA httpd と Netscape httpd で利用することができます。
以後、本稿の説明では、apache のモジュールとして PHP/FI を利用すること を前提にします。ここでは PHP/FI や apache のインストールについては触れ ませんが、それぞれの Web ページに詳しい説明がありますので、参考にして 下さい。
PHP/FI は PostgreSQL のインターフェイスも持っているので、先の CGI を PHP/FI で書き直してみましょう。なお、PHP/FI は EUC 以外は通りませんの で、漢字コードに注意して下さい。
1 <html>
2 <head><title>small city database</title></head>
3 <body>
4 都市データベースを検索するパラメータを入力して下さい。
5
6 <form method="GET" action="select.phtml">
7 都市名<input type="text" name="city">の
8
9 <select name="opt">
10 <option>北
11 <option>南
12 <option>東
13 <option>西
14 </select>
15 にある都市は?
16 <p>
17 <input type="submit" value="検索開始">
18 </form>
19 </body>
20 </html>
リスト3 test2.phtml
リスト3 は リスト1 を PHP/FI の CGI 起動用に書き直したものです。御覧の ように、form ... の行の action の指定が、select.phtml に変わっただけ です。画面的にも図3 とまったく同じです。
PHP/FI のスクリプトは、リスト 4 のように、html の中に PHP/FI プログラ ム (? ... の内側に書いてある部分) が混在するような感じになります。
1 <html>
2 <head>
3 <title>selection result</title>
4 </head>
5 <body>
6
7 <?
8 switch($opt) {
9 case "北";
10 $op="!^";
11 break;
12 case "南";
13 $op="!|";
14 break;
15 case "西";
16 $op="!<";
17 break;
18 case "東";
19 $op="!>";
20 break;
21 }
22
23 $con = pg_Connect("foo","","","","test");
24 if (!$con);
25 echo "DB test に接続できませんでした。";
26 exit;
27 else;
28 echo $city," より ",$opt," にあるのは:";
29 endif;
30
31 $query = "select c1.name from city c1, city c2 where c2.name = '$city' and c1.loc $op c2.loc;";
32 $rtn = pg_Exec($con,$query);
33 if (!$rtn);
34 echo "DB 検索エラーです。";
35 pg_Close($con);
36 exit;
37 endif;
38
39 echo "<br>";
40
41 /* pg_NumRows は検索結果件数を返す */
42 $n = pg_NumRows($rtn);
43 $i = 0;
44 while ($i < $n) {
45 echo "<li>";
46 /* pg_Result は $i 番目の結果の "name" というフィールドの値を返す */
47 echo pg_Result($rtn,$i,"name");
48 $i++;
49
50 }
51 pg_FreeResult($rtn);
52 pg_Close($con);
53 >
54 </body>
リスト4 select.phtml
まず、7 行目により、PHP/FI プログラムの開始が宣言されます。
続いて 8 行目からリスト 2 同様のアルゴリズムにより、case 文を使って 「東西南北」を PostgreSQL の operator に変換しています。ここで注目する のは、$opt 変数です。リスト 2 では cgiparse によって値が設定されていま したが、今回はいきなり $opt の値が参照されています。実は、PHI/FI では、 フォームの input タグ中の name で指定された名前が自動的に PHP/FI スク リプト中の変数名となり、その初期値が value で指定された値に設定される のです。これはとても便利な機能だと思います。なお、$city 変数についても 同様のことが言えます。
23 行目では、pg_Connect という PHP/FI の組み込み関数を使って PostgreSQL に接続しています。御覧のように、PHP/FI では関数は
関数名(引数1, 引数2, ...)という形を取ります。pg_Connect の場合、第 1 引数は データベースホスト 名、第 2 引数は 接続ポート番号、第 3 引数は接続オプション、第 4 引数 は接続するデータベース名です。今回は第 2 引数と第 3 引数は標準のままで 良いので、省略値の意味で null 文字列 ``'' を渡しています。
pg_Connect の戻り値は「ハンドル」です。以後、データベースにアクセスす るたびにこのハンドルが使われます。もしハンドルの値が 0 であった場合は エラーですので、26 行目で明示的に PHP/FI のパースを終了しています。
31 行目で select 文を作り、32 行目で pg_Exec 関数により SQL を発行します。
正常な場合は、42 行目の pg_NumRows で検索結果の件数を求めます。そして 44 〜 50 行目の while 文の中で、ちょっと見栄えを良くするために タ グを出力した後 pg_Result 関数で検索結果の文字列を取り出しています。 pg_Result 関数は、第 1 引数が pg_Exec が返した検索結果へのハンドルで、 第 2 引数が検索結果の「行」の指定、第 3 引数がカラム名です。
51 行目はメモリ解放などの後始末、52 行目はデータベースとの接続を切り離 します。53 行目は PHP/FI プログラムの終りを示します。
ところで、pg_Connect などの関数を使わずにPHP/FI の組み込み関数 Exec を 使って psql を外部プロセスとして呼び出すこともできます。この場合の問題 点は、
なお、 図 5
を良く見ると、下の方に何やらアクセス統計らし きものが見えていますが、これは PHP/FI が自動的に付けてくれるものです (付けないこともできる)。これもなかなか気が効いた機能と思います。