next up previous contents
Next: PHP/FI Up: WWWでデータベースにチャレンジ!〜PostgreSQLを使って Previous: PostgreSQL の簡単な使い方

PostgreSQL を CGI で使う

次に、上記のような問い合わせを、ユーザ・インターフェイスに Web を使っ て行なうことを考えましょう。Web ブラウザの画面からデータベースを検索で きれば、呪文のような SQL を入力しなくて済むので使い勝手が向上します。 今回はごく単純に、「都市名」と、その都市に対して「東西南北」のどれかを 指定することによって、データベースを検索して条件にあった都市名を表示す るようにしましょう。このような画面は、「フォーム」を使うと簡単に実現で きます(図 3 、リスト 1)。

     1	<html>
     2	<head><title>small city database</title></head>
     3	<body>
     4	都市データベースを検索するパラメータを入力して下さい。
     5	
     6	<form method="GET" action="select.cgi">
     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>

リスト1test.html

フォームを使うと、ブラウザ上にユーザ入力のエリアが表示されます。フォー ムには、入力エリアとしていくつか種類がありますが、今回は都市名の入力エ リアとして、自由にテキストを入力できる ``text'' (7 行目)と、東西南北の指 定のために ``select'' (9 行目) を使います。

その他、入力データを Web サーバに送信するためのボタンが必要ですが、こ れは 17 行目の <input type=submit...> で指定しています。

6 行目の <form method...> はフォームの開始を指示しますが、それ以外 に、起動されるべき CGI プログラムを指示すると言う重要な役割があります。 action=``select.cgi'' がそれですが、この場合、リスト1の html ファイル と select.cgi が Web サーバ上で同じディレクトリにあることが前提になっ ています。もしも select.cgi を特定のディレクトリに置く必要がある場合は、 パス名を追加して下さい。たとえば、action=``/cgi-bin/select.cgi''などと なるでしょう。このほか、お使いのサーバの設定によって考慮すべき点がある かも知れません。うまくいかない場合は、サーバの管理者に相談してみて下さ い。

そのほかに気をつけることとしては、

  1. PostgreSQL を使う関係上、HTML ファイル、CGI スクリプトはすべて EUC で書いて下さい。
  2. CGI を実行する前に、CGI を実行する UID が PostgreSQL のデータベー スにアクセスできるように、前出の createuser で登録しておく必要がありま す。通常、CGI の実行ユーザは httpd サーバーと同じで、 ``nobody'' と呼ばれ るアカウントが設定されることが多いようです。この場合は、

	createuser nobody

となります。

gif

リスト 1 のフォームで、「検索開始」ボタンを押すと、リスト 2 の shell script select.cgi が起動されます。このプログラムの処理概要は以下のよう になります。

  1. 適切な HTTP ヘッダを生成する
  2. フォームから渡されたパラメータを解析する
  3. データベースを検索する
  4. 結果を標準出力に吐き出す

では、リスト2 を見ながら具体的な処理の流れを追っていきましょう。

     1	#!/bin/sh
     2	cgiparse=/usr/local/etc/cgiparse
     3	psql=/usr/local/postgres95/bin/psql
     4	dbhost=foo
     5	
     6	echo Content-type: text/plain
     7	echo
     8	
     9	city=`$cgiparse -value city`
    10	opt=`$cgiparse -value opt`
    11	
    12	case $opt in
    13	北)
    14	op='!^';;
    15	南)
    16	op='!|';;
    17	西)
    18	op='!<';;
    19	東)
    20	op='!>';;
    21	esac
    22	
    23	query="select c1.name from city c1, city c2 where c2.name = '$city' and c1.loc $op c2.loc;"
    24	
    25	echo "$city より $opt にあるのは:"
    26	$psql -h $dbhost -t -c "$query" test

リスト2 select.cgi

6 行目では、 ``Content-type: text/plain'' という HTTP ヘッダを生成してい ます。通常 HTTP ヘッダは Web サーバが自動的に作ってくれるので意識する 必要がないのですが、CGI では少なくとも Content-type: というフィールド を自前で用意する必要があります。これを忘れると、何もブラウザに表示され ないので注意して下さい。なお、Content-type: フィールドは Web サーバに 対して CGI が生成するドキュメントの種類を教えるためのもので、この例で は、text/plain (いわゆる「プレーン・テキスト)となっています。

HTTP ヘッダの終了を示すために 7 行目で空行を出力した後、9, 10 行目でフォー ムから渡されたパラメータの解析を cgiparse を使って行ないます。cgiparse は、CERN httpd という Web サーバに付いてくるツールで、CERN httpd 以外 の環境でも使うことができます。

ここで、フォームに入力されたパラメータについてお話します。この例では、 select.cgi が起動されるときに 環境変数 QUERY_STRING に以下のような形式 でパラメータがセットされます。

	name1=param1&name2=param2...

name1, や name2 はフォームの name=... で指定された文字列です。御覧のよ うに、name の後に = が来て、その後に入力された値がセットされます。 <select ..> の場合には、<option> で指定された値のうち、ユーザが選択し た値が入ります。複数の入力項目の区切りは ``&'' です。たとえば、リスト 1 で、都市名に ``東京'' 、東西南北の選択が ``北'' であった場合、

	city=東京&opt=北
となるはずですが、実際には
	city=%C5%EC%B5%FE&opt=%CB%CC
が QUERY_STRING にセットされます。%C5 などの暗号のような文字列は 「URL エンコーディング」と呼ばれる規則にしたがって変換された結果です(実はさ きほどの ``='' や ``&'' の使い方も URL エンコーディングの一部なのですが)。 この規則によれば「値」の文字列は以下の規則にしたがって変換されます。

つまり %C5%EC%B5%FE は「東京」を、%CB%CC は「北」をそれぞれ表す EUC コー ドの16 進数だったわけです。

こういったややこしいことは cgiparse を使えば簡単に処理できます。 cgiparse は -value で指定された文字列を name とみなし、URL エンコーディ ングをもとに戻し、標準出力に吐き出します。select.cgi では cgiparse を 使って 9 行目、10 行目のように shell 変数 city, opt に値をセットしてい ます。

cgiparse と同じ機能を持つプログラムは、ほかにもたくさんあります。たと えば、perl で書かれた cgi-lib.pl (http://www.bio.cam.ac.uk/cgi-lib/) は perl で CGI を使う場合に大変便利です。

フォームから渡された検索パラメータが解析できれば、後は select 文を作る だけです。12 行目から 21 行目までの case 文で「東西南北」を対応する PostgreSQL の operator に変換して shell 変数 op にセットし、23 行目で $city と $op を使って SQL を作っています

最後の行で psql のコマンドを発行します。ここで、psql のオプション -h は PostgreSQL の動いているホストを指定し、-c はインタラクティブではな く与えられた問い合わせをバッチ式に実行します。また、コマンドラインから 起動する場合と違って、カラム名とか ``(5 rows)'' のようなコメントを psql に出力してもらう必要はありませんから、-t でこれを抑止しています。

CGIによる検索結果
CGIによる検索結果



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