インターネット上の掲示板では、入力エリアにデータを入力し「OK」を押すと、実際に書き込みが行われる。このようにHTML文書内にデータ入力エリアを配置し、適宜入力した上でボタンを押すとあらかじめ定められた処理を行い、結果が表示されるような仕掛けがある。このような仕組みをCGI(Common Gateway Interface)という。
CGIのデータ入力窓の集合を入力フォームという。 以下の入力フォームに値を入力、あるいは選択し「OK」ボタンを押してみよう。
上のフォームで入力もしくは選択された値はCGI変数という特別な変数でCGIスクリプトに送られる。このCGIスクリプトがRubyもしくはPerlという言語で書かれており、そこに書かれた内容に応じて何らかの処理を行い、結果を示すHTML文書を出力する。これを概念的に示すと以下のようになる。
氏名:[山田太郎] 個数を選択: 鉛 筆(100円):[2] 消しゴム(100円):[1] ノート (150円):[0] ファイル(300円):[3] 蛍光ペン(120円):[2] [OK][reset] |
→ |
Ruby(Perl)プログラムが値を受け取り、何らかの処理を実行すると同時に、結果出力用のHTML文書を生成する。 |
→ |
<html> <head> <title>結果!</head> </head> <body> <p>うんたら</p> </body> </html> |
CGIは以下の3つのファイルにより構成される。
CGIを構成するファイルのうち「入力したデータを受け取って処理をするプログラム」がRubyのプログラムに相当する。
通常は、Rubyプログラムは自分で作成したruby/などのディレクトリに保存していたが、Web上で実行させるためには、putlic_htmlの中にプログラムのファイルを置く。htmlファイルと同様に、ブラウザから閲覧させたいファイルは全てpublic_htmlのディレクトリ内に置いて置かなければならない。
ここでは、CGIを利用するためのディレクトリをpublic_htmlの中に新たに作成し、CGI関連のファイルは全てその中に保存しておくことにする。
仮に、作成するディレクトリがcgi-binである場合、まず
irsv{c10xxxx}% cd public_html[Return] irsv{c10xxxx}% mkdir cgi-bin[Return]
というように、mkdirコマンドでcgi-binというディレクトリを作成する。
次に、「このディレクトリ内でCGIを利用する」という宣言を行う。具体的にはcgi-binのディレクトリ内に.htaccessという名前のファイルを作成する。
このファイルを作成するためには、emacsでFile:~/public_html/cgi-bin/.htaccess[Return]とすればよい。ファイルを新規作成したら、以下の内容を記述して保存する。
AddHandler cgi-script .rb
これにより、以後このディレクトリに作成する.rbの拡張子を持つファイルは、全てCGIスクリプトと認識される
*後ほど実際に自分で作成したCGIプログラムを動かすが、もしもうまく動かない場合は、.htaccessに上記の代わりに次のように記述してみること。
AddHandler cgi-script .rb Options +ExecCGI
HTML言語を使用したWebページの記述方法については、1年生の情報リテラシーIIで実施済みである。ここでは入力フォームの作り方について確認する。
冒頭で示した入力フォームとそのソースを見てみよう。
<form method="POST" action="./kakaku.rb"> <p class="item">氏名: <input type="text" name="name" maxlength="40"><br> 個数を選択:<br> 鉛 筆(100円):<select name="pencil"> <option> 0 <option> 1 <option> 2 <option> 3 </select><br> 消しゴム(100円):<select name="eraser"> <option> 0 <option> 1 <option> 2 <option> 3 </select><br> ノート (150円):<select name="note"> <option> 0 <option> 1 <option> 2 <option> 3 </select><br> ファイル(300円):<select name="file"> <option> 0 <option> 1 <option> 2 <option> 3 </select><br> 蛍光ペン(120円):<select name="pen"> <option> 0 <option> 1 <option> 2 <option> 3 </select><br> <input name="ok" type="submit" value="OK"> <input name="ng" type="reset" value="reset"> </p> </form>
ソースを見ると、入力フォームは、form要素(<form>タグ)を使って書かれていることがわかる。form要素の基本構造は
<form method="メソッド" action="./スクリプト"> </form>
となる。メソッドの部分はGETまたはPOSTのどちらかを指定する。GETは最大で255文字までしか送ることができない(今回は名前と商品の購入数があるが、これらを全て含めて255文字)。項目数が多い場合や長い文章を入力させる場合はPOSTを指定する。ここではPOSTを使うものとして説明を続ける。
スクリプトの部分は入力データの引渡し先である。このソースを見ると、./kakaku.rbとなっており(./は同一ディレクトリをあらわすので)、cgi-binディレクトリの中にあるkakaku.rbがデータを受け取って処理をしていることがわかる。
このformの例では、
をそれぞれ受け取り、kakaku.rbに引き渡していることがわかる。
CGIスクリプトとなるRubyプログラムでは、まず冒頭で必ず以下を記述する。
#!/usr/bin/env ruby
require 'cgi'
c = CGI.new("html4")
print "Content-type: text/html; charset=EUC-JP\n\n"
1行目は必ず記述するおまじないであるが、CGIスクリプトを書く場合は通常とは異なるので注意しよう。
c = CGI.new("html4")で、HTMLの入力フォームから引き渡された値が、変数cにハッシュ値として代入される。変数cはどんな名前にしても構わない。
cにハッシュ値として代入されていることから、各入力値を取り出すためには、HTMLが引き渡す際に設定したnameやpencilをkeyとするvalueという形で指定すればよい。
例えば
var1 = c["pencil"]
とすれば、keyのpencilに対応するvalueがvar1に代入される。
以下は、上記の入力フォームに入力後、HTMLが引き渡すRubyプログラム(kakaku.rb)である。
注意
このRubyプログラムは、~/public_html/cgi-bin/の中に保存すること。
保存後には、CGIスクリプトとして実行できるようにするため、ktermで以下を入力すること。
irsv{c10xxxx]% chmod 755 kakaku.rb[Return]もしくは
irsv{c10xxxx]% chmod +x kakaku.rb[Return]
#!/usr/bin/env ruby require 'cgi' c = CGI.new("html4") print "Content-type: text/html; charset=EUC-JP\n\n" name = c["name"] var1 = c["pencil"] var2 = c["eraser"] var3 = c["note"] var4 = c["file"] var5 = c["pen"] sum1 = 100 * var1.to_i sum2 = 100 * var2.to_i sum3 = 150 * var3.to_i sum4 = 300 * var4.to_i sum5 = 120 * var5.to_i sum = (sum1 + sum2 + sum3 + sum4 + sum5) * 1.05 print "<html> <head><title>お会計</title></head> <body>\n" print "<h1>#{name}さんのお会計</h1>\n" print "<p>鉛 筆が#{var1}個で#{sum1}円</p>\n" print "<p>消しゴムが#{var2}個で#{sum2}円</p>\n" print "<p>ノート が#{var3}個で#{sum3}円</p>\n" print "<p>ファイルが#{var4}個で#{sum4}円</p>\n" print "<p>蛍光ペンが#{var5}個で#{sum5}円</p>\n" print "<p>税込み合計で#{sum.to_i}円です。</p>\n" print "</body>\n" print "</html>\n"
このプログラムでは、上半分でHTMLより送られた値をname、var1、var2、var3、var4、var5、var6に代入し、sum1〜sum5、sumを計算している。
下半分では、結果をHTML形式で出力するために<html>や<body>、<p>などのタグをprintを使って記述している。
プログラムの下部にある#{・・・}という記法は、その部分をRubyの式をしてその値に置き換える働きを持つ。例えば、
print "10+20は#{10+20}です\n"
とすると
10+20は30です
と表示される。また、
x=30
print "10+20は#{x}です\n"
とすると
10+20は30です
と表示される。
自分でCGIを設置して動作を確認する。ここまでで既にcgi-binディレクトリを作成し、.htaccessとkakaku.rbを設置してきたので、最後に入力データを引き渡すHTMLを作成し、実際に実行してみる。
うまく実行できたら、入力フォームのあるHTML文書のURL(おそらくhttp://roy.e.koeki-u.ac.jp/~学籍番号/cgi-bin/xxx.htmlのようになるはず)を報告する。
HTML文書を1から作成するのは大変なので、以下を保存してそのまま活用してよい。
ハイパーリンクを右クリックし、対象ファイルを~/public_html/cgi-bin/の中に保存すること。
制限時間は10分程度。出席点は2点。提出要領は下記の通り。
Tips:emacsでの日本語入力のオンオフはCtrl-oです
Tips:Mewによるメールの送り方はMewコマンドを参照
これまで、入力した値に基づいて計算を行って結果を表示するCGIスクリプトについて見てきたが、今度は一歩進んで、入力した値により出力を切り替える例を作成してみよう。つまりif文を用いて結果を切り替える。
今回はラジオボタン(これ→)やチェックボックス(これ→)が追加されている。これらのパーツはいずれもいずれもinput要素で作成できる。パーツの使い分けはtype属性で指定する。
<form method="POST" action="./shinri.rb"> <p class="item">氏名: <input type="text" name="name" maxlength="40"><br> 性別: <input type="radio" name="rd" value="男性">男性 <input type="radio" name="rd" value="女性">女性 <input type="radio" name="rd" value="不明">どちらでもない<br> 以下の各項目について当てはまるものに全てチェックをつけてください。<br> <input type="checkbox" name="box1" value="1"> いろいろ勉強して自分を深めたい<br> <input type="checkbox" name="box2" value="1"> 社会に出て成功したいと思う<br> <input type="checkbox" name="box3" value="1"> いつも何か目標を持っている<br> <input type="checkbox" name="box4" value="1"> 手がけたことは最善を尽くしたい<br> <input name="ok" type="submit" value="OK"> <input name="ng" type="reset" value="reset"> </p> </form>
以下は、上記のHTMLからの入力データを受け取り、処理をして結果のHTML文書を出力するCGIスクリプトであるshinri.rbである。先ほどと同様に変数cのハッシュ値として入力値を取り出し、チェックをした項目数に応じてif文でメッセージを変化させていることがわかる。
#!/usr/bin/env ruby require 'cgi' c = CGI.new("html4") print "Content-type: text/html; charset=EUC-JP\n\n" namae = c["name"] seibetsu = c["rd"] q1 = c["box1"] q2 = c["box2"] q3 = c["box3"] q4 = c["box4"] point = q1.to_i + q2.to_i + q3.to_i + q4.to_i print "<html> <head><title>診断結果</title></head> <body>\n" print "<h1>#{namae}さん(#{seibetsu})の診断結果</h1>\n" print "<p>あなたがチェックをした項目数は#{point}個です。</p>\n" print "<p>" if point == 4 print "やる気満々ですね。このまま頑張って!\n" elsif point == 3 print "結構頑張り屋さんですねえ。この調子で。\n" elsif point == 2 print "うーん。まあまあですかねえ\n" elsif point == 1 print "うーん。うーん。もうちょっとやる気見せましょう。\n" else print "やる気ないですね。\n" end print "</p>\n" print "</body>\n" print "</html>\n"
以下のうちいずれかを選んで解答する。
問題1(10点満点):CGIを使って自由に何かを作成する。10点満点だが、単に授業用のページ(他の先生も含む)に掲載されているものを複写し、多少言葉を変えただけの場合はプログラム点の配点を最低点とする。
問題2(7点満点):これまで作成してきたプログラムのうち一番頑張ったものをWebページに掲載する。文法の良し悪しで採点する。
問題1の場合
問題2の場合
Tips:emacsでの日本語入力のオンオフはCtrl-oです
Tips:ktermでのプログラムの実行結果をメールに貼り付けるには、コピーしたい箇所をマウスで選択し、emacs(Mew)上でマウスの真ん中ボタンをクリックする
Tips:Mewによるメールの送り方はMewコマンドを参照