next up previous contents
Next: おわりに Up: WWWでデータベースにチャレンジ!〜PostgreSQLを使って Previous: PostgreSQL を CGI で使う

PHP/FI

最近、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 文の中で、ちょっと見栄えを良くするために <li> タ グを出力した後 pg_Result 関数で検索結果の文字列を取り出しています。 pg_Result 関数は、第 1 引数が pg_Exec が返した検索結果へのハンドルで、 第 2 引数が検索結果の「行」の指定、第 3 引数がカラム名です。

51 行目はメモリ解放などの後始末、52 行目はデータベースとの接続を切り離 します。53 行目は PHP/FI プログラムの終りを示します。

ところで、pg_Connect などの関数を使わずにPHP/FI の組み込み関数 Exec を 使って psql を外部プロセスとして呼び出すこともできます。この場合の問題 点は、

ということです。例題のように簡単な処理では、 psql を起動する方式でも問 題ありませんが、ある程度複雑な処理が見込まれる場合は、最初から pg_Connect などを使うようにした方が良いでしょう。

なお、 図 5

を良く見ると、下の方に何やらアクセス統計らし きものが見えていますが、これは PHP/FI が自動的に付けてくれるものです (付けないこともできる)。これもなかなか気が効いた機能と思います。



Tatsuo Ishii
1998年07月06日(月) 14時34分03秒 JST