CGI入門

HTML文書内にあるデータ入力窓とそれらを受け渡すスクリプト 名を書いておき、ボタンを押すとそのスクリプトに入力値が 渡るようなしくみをCGI(Common Gateway Interface)という。

CGIのしくみ

CGIのデータ入力窓の集合を入力フォームという。 以下の入力フォームに値を入力、あるいは選択し「OK」ボタンを押してみよう。

名前↓
さんの誕生日は?

上の入力窓に入れられた値は全てCGI変数という特別な 変数でCGIスクリプトに送られる。 自分で作るプログラムではその変数を受け取りそれに応じた処理をした上で、 結果を表すHTML文書を出力する。

[taro]さんの誕生日は?
[1992]年[ 3]月[1]日
[OK][reset]

「Rubyスクリプト」
値を受け取り
HTMLを出力
<html>
<head>
<title>結果発表!</title>
</head>
</body>
<p>........</p>
</body>
</html>

CGIの作り方

CGIは、利用者にデータを入力してもらうためのHTML文書と そこから送られて来るデータを受け取って処理をするプログラムファイルを 作る。さらに、Webサーバに対して「ここでCGIプログラムを利用する」ことの 宣言を行なう必要がある。

  1. CGI利用宣言 → .htaccessファイルの作成
  2. 入力フォームのHTML文書作成
  3. 処理プログラムの作成

順を追って行なう。

CGIプログラムの利用宣言

「この場所でCGIを利用する」ためのディレクトリを作成し、そこに .htaccessという名前のファイルを作成する。ここではたとえば、 ~/public_html/mycgi というディレクトリを作成し、 そこでCGI利用宣言をするものとする。まず

% cd ~/public_html
% mkdir mycgi

としてディレクトリを作成する。次にEmacsで ~/public_html/mycgi/.htaccess ファイルを新規に開き、 以下の内容を記述して保存する(コピーペーストしてよい)。

AddHandler cgi-script   .rb
Options +ExecCGI

以後、このディレクトリに作成する .rb という名前で 終わるファイルはCGIスクリプトと認識される。

HTML文書の構成

次は入力フォームを構成するHTML文書を作る。入力フォームは form要素を使って記述する。form要素は

<form method="メソッド" action="./スクリプト">
 〜〜〜
</form>

のように記述する。メソッドの部分は GET または POST のどちらかを指定する。文章など、長いデータを入力させた いときはPOSTを指定する。

以下のform要素例は

入力させ、./btype.rb というスクリプトに 入力値を渡すためのHTML記述である(該当部分抜粋)。

<form method="POST" action="./btype.rb">
<p>お名前: <input name="namae" type="text" maxlength="40"><br>
血液型: <select name="blood">
  <option> A
  <option> AB
  <option> B
  <option> O
 </select><br>
<input type="submit" value="OK">
<input type="reset" value="reset"><br></p>
</form>

上記の入力フォームのみを含むHTML文書の例を btype.htmlに示す。

次節で、./btype.rbの作り方を示す。

CGIスクリプトの構成

CGIスクリプトとなるRubyプログラムでは、最低限以下の内容を記述して 作成する。

#!/usr/bin/env ruby
# coding: euc-jp

require 'cgi'
c = CGI.new(:accept_charset => "EUC-JP")
print "Content-type: text/html; charset=EUC-JP\n\n"

変数cはどんな名前でもよい。このあとに、HTML文書となり得 る文字列を順次出力していく。

requireは、プログラムに必要な 外部モジュールを現在のプログラムに取り込む記法で、

require 'cgi'

はCGIプログラムを組むのに便利なクラスが定義された cgi.rb を取り込む宣言である。これで以下のようにCGIクラスが 使えるようになる(CGI.newの部分)。

CGIプログラムに渡された入力値を取り出すには、CGI.new を受け取った変数のハッシュ値として取り出す。以下の例はform入力された パラメータ namaeblood を単にHTML文書形式で 出力するRubyプログラムである。

btype.rb

#!/usr/bin/env ruby
# coding: euc-jp

require 'cgi'
c = CGI.new(:accept_charset => "EUC-JP")
print "Content-type: text/html; charset=EUC-JP\n\n"

name = c["namae"]  # フォームに記入されたnamae変数を取り出す
bt   = c["blood"]  # フォームに記入されたblood変数を取り出す

print "<html>
<head><title>Blood type</title></head>
<body>\n"

print "<h1>#{name}さんの血液型</h1>\n"

print "<p>#{name}さんは#{bt.upcase}型ですね!</p>\n"
print "</body>\n"
print "</html>\n"

プログラムの "" で囲まれた文字列中で利用している #{...}という記法はその部分をRubyの式としてその値に 置き換える働きを持つ。たとえば、

print "1+2は#{1+2}です\n"

とすると、

1+2は3です

と出力される。

このCGIを動かす例が以下の入力フォームである。

お名前:
血液型:

処理の切り替え

少し進んで、入力した値により出力を切り替える例を作成してみよう。 メッセージ出力部分をifによって切り替える。

お名前:
血液型:

このCGIのソース:btype2.rb

CGIプログラムのデバッグ

簡単なRubyプログラムでも、CGIとして動かすには困難がともなう。 なぜなら、プログラムを起動して出てくるエラーメッセージなどが見えないから である。文法エラーなどもWebブラウザ経由では見ることができない。

cgi.rbモジュールを利用したプログラムはCGI経由だけでなく、 シェル上でもデバッグできる。上記の の場合は、HTMLからrbに渡すCGI変数として name, blood を利用してる。このプログラムをコマンドラインで デバッグする場合以下のように起動する。

% ./btype.rb
(offline mode: enter name=value pairs on standard input)
name=太郎
blood=A
[C-d]

CGI変数の値を

変数1=1
変数2=2
変数3=3
  :

の形式で入力し、最後にC-dをタイプすればよい。

入力する値が毎回決まっているときは、上記のような 変数=を1行ごとに書き連ねた ファイルを用意し

% cat そのファイル | ./btype.rb

とすると作業効率がよい。上記の実行例のとおりの値でよければ

name=太郎
blood=A

という内容のファイルを作成する。

以上のような起動方法で、正しくHTML文書が出力されたらWebブラウザ経由で 起動する。ブラウザ経由でアクセスしてエラーになる場合は、Webサーバ(roy)に ログインし /usr/local/apache2/logs/error_log ファイルの 最後の方を参照する。

% ssh roy
% less +G /usr/local/apache2/logs/error_log

error_log ファイルの末尾を表示し、bkを押してさかのぼってエラーメッセージを探す。あるいは、 ブラウザでCGIプログラムをアクセスする前にktermで、

% tail -f /usr/local/apache2/logs/error_log

としておくと、アクセスするのと同時にエラーが出力される。 デバッグが終わったら tail を C-c で止め、 最後にroy からログアウトするのを忘れないこと。

formで使える入力用要素

input要素

なんらかの値を入力させる場合に、input要素に入力方法と変数を指定する。 入力方法は type属性で、変数名は name 属性で指定する。以下に入力方法の種別と使用例を示す。 他の属性も付けた例を示すが、 最低限必要なのは name である。 type を省略すると text と見なされる。

text

1行だけの文字列入力。

<input name="v_text" type="text" value="Hello" size="40">

変数 v_text に初期値 "Hello" を入れて40字分の枠を作る。

初期値を省略すると空欄。

password

text と同様だが、入力文字をアスタリスクで隠す。

<input name="v_password" type="password" size="20" maxlength="12">

変数 v_password に最大文字数12字のパスワード入力を入れる。

ただし、パスワードの値がCGIプログラムに渡されるときは暗号化など 一切されないので、盗聴されても構わないものでしか使えない。

checkbox

チェックボックスを作る。ONのときの値とOFFのときの値を value 属性で指定する。

<input name="v_checkbox_1" type="checkbox" value="morning">
朝御飯OK<br>
<input name="v_checkbox_2" type="checkbox" value="night">
夕飯OK

「朝御飯OK」がチェックされていたら変数 v_checkbox_1"morning" に 「夕飯OK」がチェックされていたら変数 v_checkbox_"night" を代入させる。
朝御飯OK
夕飯OK
チェックされないときは空文字列 "" が代入される。

radio

ラジオボタンを作成する。name属性で同じ変数名 を持つものどうしがグループ化され、どれかひとつをチェックすると 他はクリアされる。

<input name="v_radio" type="radio" value="1">地球人
<input name="v_radio" type="radio" value="2">宇宙人
<input name="v_radio" type="radio" value="3">仙人

地球人 宇宙人 仙人

たとえば「仙人」を選ぶと v_radio 変数に "3" が代入される。

submit, reset

入力値の送信またはリセットボタンを作成する。

<input type="submit" value="[送信]">
<input type="reset" value="[リセット]">

←これを押すと上記の入力値がすべてリセットされる。

hidden

隠れ変数を設定する。CGIプログラムに必ず渡したい 変数値を見えないところで指定する。

<input name="v_hidden" type="hidden" value="第3ステージ">

上記を書いてもWebページには何も表示されないが CGIには v_hidden 変数が渡される。

select要素

選択肢を提示してそのうち1つまたは複数を選ばせるには selectとoptionを組み合わせる。

好きな季節
<select name="v_select">
 <option>春 
 <option value="Summer" selected>夏
 <option value="Autumn">秋 
 <option value="Winter">冬 
</select>

好きな季節
(value指定のない「春」を選択すると「春」そのものが値となる)

このように、selected を付けておいたオプションが 選択初期値となる(上の場合「夏」)。 selected を付けなければ先頭項目が選択された状態で始まる。

selectmultiple 属性を付けると 複数選択が可能になる。

好きな曜日
<select multiple name="v_select_multi">
 <option value="Sunday" selected>日
 <option value="Monday">月
 <option value="Tuesday">火
 <option value="Wednesday">水 
 <option value="Thursday">木
 <option value="Friday">金
 <option value="Saturday" selected>土
</select>

好きな曜日

Firefoxで複数選択するには Ctrlクリック で行なう。

テキストエリア

長文を入力させるためには textarea を用いる。 入力エリアの行と桁数はそれぞれ rowscols 属性で指定する。

<textarea name="v_textarea" cols="60" rows="5">
これを消してメッセージをどうぞ
</textarea>

その他のフォーム

フォーム制御の詳細は HTML 4.01仕様書: フォーム を参照のこと。

発展

値を永続させる

CGIへの画像投稿


目次