まず、以下の3種類のファイルを作成する:
これら(下にソースコードが書かれている)を作成した後、以下の手順でWWWサーバに設置する:
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="Shift-JIS">
<title>CGIの例</title>
<meta name=viewport content="width=device-width, initial-scale=1">
<style type="text/css">
body{
background-color: mint;
}
form{
display: inline;
}
</style>
</head>
<body>
<div style="width: 600px; margin: 0 auto; text-align: center;">
<h1>評価してください</h1>
<p>
<img src="http://www.ipc.hokusei.ac.jp/~z00328/adjyou/ex/sbuc.gif" alt="作品" >
</p>
<form method="POST" action="hw02.cgi">
<input type="hidden" name="rating" value="high">
<!--HIGH-->人
<input type="submit" value="高く評価">
</form>
<form method="GET" action="hw02.cgi">
<!--LOW-->人
<input type="hidden" name="rating" value="low">
<input type="submit" value="低く評価">
</form>
</div>
</body>
</html>
[hw02.cgi]
#! /usr/bin/perl
#use strict;
my $top_page = "hw02.cgi";
my $filename = "hw02.dat"; # 1行だけのCSVファイル。高い評価点,低い評価点
my $show_list_tmpl = "hw02.html";
my %param;
my @data;
%param = get_param();
if( $param{rating} ne "" ){
read_records();
update_data($param{rating});
}
read_records();
show_list();
exit;
################### subroutines ##################
sub update_data
{
my $Rating = $_[0];
# $data[0]しかないので、それだけを変更
if( $Rating eq 'high' ){
++( $data[0]->{high} );
}elsif( $Rating eq 'low' ){
++( $data[0]->{low} );
}else{
return;
}
# 書き込みモードでファイルを開く
open(OUT, ">$filename") || &error("Cannot open $filename: $!");
foreach (@data){
if($_->{high} eq ""){ next;} # データがNULLの場合は書き出さない。
print OUT "$_->{high},$_->{low}\n";
}
# ファイルを閉じる
close(OUT);
}
sub read_records
{
my( $high, $low );
# @dataを初期化
@data =();
# 読み取りモードでファイルを開く
open(IN, "<$filename") || &error("Cannot read $filename: $!");
while(<IN>){
chomp;
( $high, $low ) = split(/,/, $_);
# 無名ハッシュを配列にする
push @data,
{
'high'=>$high,
'low'=>$low
};
}
# ファイルを閉じる
close(IN);
}
sub show_list
{
my $table_list;
# 読み取りモードでファイルを開く
open(IN, "<$show_list_tmpl") || &error("Cannot read $show_list_tmpl: $!");
print "Content-Type: text/html;charset=Shift_JIS;\n\n";
while(<IN>){
s/<!--HIGH-->/$data[0]->{high}/g;
s/<!--LOW-->/$data[0]->{low}/g;
print $_;
}
}
# 入力データの取得
sub get_param
{
my($query, $key, $value, %param);
if($ENV{REQUEST_METHOD} eq "GET"){
$query = $ENV{QUERY_STRING};
}else{
read(STDIN, $query, $ENV{CONTENT_LENGTH});
}
foreach(split(/&/, $query)){
($key, $value) = split(/=/, $_);
$value =~ s/\+/ /g;
$value =~ s/%([\da-f][\da-f])/pack("C", hex($1))/egi;
## &jcode'convert($value, 'euc');
$value =~ s/\r//g;
$param{$key} = $value;
}
return %param;
}
# エラー表示
sub error
{
print "Content-Type: text/html\n\n";
print <<"---EOF---";
<html><head><title>Information</title></head>
<body>
<span sylte="color: red;"> $_[0]</span>
<form method="GET" action="$top_page">
<input type=SUBMIT value="最初のページに戻る">
</form>
</body></html>
---EOF---
exit;
}
[hw02.dat]
0,0
hw02.htmlのimg要素のsrc属性を変更(上のソースの網掛けの部分)して、自分で用意した画像を評価できるように改造しよう。また、h1要素のタイトル文字なども、適切なものに書き換えよう。
この作業のコツは、hw02.htmlだけを変更すれば良いことと、どのように表示されるかを確認するためには、ローカルでhw02.htmlをブラウザで開くことで確認しながら行うことである。
hw02.htmlの修正が終わったら、hw02.htmlと自分で用意した画像ファイルをWWWサーバにアップロードして、動作を確かめよう。
Perlは汎用のプログラミング言語と言えるが、Webプログラミングに特化したものとして、PHPがある。PHPで宿題02と同様の動作をさせるサンプルを、参考として紹介する。PHPはPerlと違って、パーミッションの設定が不要なところも簡便で良い。
サンプルのページのソースをブラウザで見てみると、下のPHPのソース・スクリプトの部分(<?php 〜 ?>)は表示されないか実行結果に置き換わっていることが確認できる。
[hw02.php]
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="Shift-JIS">
<title>CGIの例</title>
<meta name=viewport content="width=device-width, initial-scale=1">
<style type="text/css">
body{
background-color: #fff;
background-image: linear-gradient( to top, rgba(255, 255, 255, 1.0), rgba( 0, 0, 255, 0.5) );
}
form{
display: inline;
}
</style>
<?php
ini_set('display_errors', 1);
$file="hw02.dat";
$path = ".";
if( isset($_POST["rating"]) ){
// ファイルの読込
$size = filesize($path ."/" . $file);
$pointer = fopen($path . "/" . $file, "r");
$line = fgets($pointer, $size);
$line = chop($line);
fclose($pointer);
$point = explode(",", $line);
// ポイントの更新
if( $_POST["rating"] == "high" ){
$point[0] += 1;
}elseif( $_POST["rating"] == "low" ){
$point[1] += 1;
}
$str = implode(",", $point) . "\n";
// ファイルへ書き込み
$pointer = fopen($path . "/" . $file, "w");
@fwrite($pointer, $str);
fclose($pointer);
}
// ファイルの読込
$size = filesize($path ."/" . $file);
$pointer = fopen($path . "/" . $file, "r");
$line = fgets($pointer, $size);
$line = chop($line);
fclose($pointer);
$point = explode(",", $line);
?>
</head>
<body>
<div style="width: 600px; margin: 0 auto; text-align: center;">
<h1>舌を出す黒猫</h1>
<p>
<img src="./cat.gif" alt="作品" >
</p>
<form method="POST" action="hw02.php">
<input type="hidden" name="rating" value="high">
<?php print( $point[0] ) ?>人
<input type="submit" value="高く評価">
</form>
<form method="POST" action="hw02.php">
<?php print( $point[1] ) ?>人
<input type="hidden" name="rating" value="low">
<input type="submit" value="低く評価">
</form>
<p><?php print("PHP version"); ?></p>
</div>
</body>
</html>