宿題02

1. 画像の評価をカウントするCGIプログラムのサンプル

まず、以下の3種類のファイルを作成する:

hw02.html
表示されるwebページの雛形となるHTMLファイル
hw02.cgi
hw02.htmlの評価のカウントをhw02.datのデータで置き換えて表示するCGIスクリプト。評価ボタンをクリックしたときの処理も行う。
hw02.dat
高い評価と低い評価のカウントを保存するCSVファイル(コンマ区切り)。

これら(下にソースコードが書かれている)を作成した後、以下の手順でWWWサーバに設置する:

  1. 各自の~/public_html/hw/にhw02という名前のサブディレクトを作成せよ。
  2. hw02.html、hw02.cgiとhw02.datを~/public_html/hw/hw02/中にアップロードせよ。
  3. hw02.cgiのパーミッションを755、hw02.datのパーミッションを606に設定せよ(FFFTPで設定可)。
  4. ブラウザで、http://www.ipc.hokusei.ac.jp/~k18xxx/hw/hw02/hw02.cgiにアクセスして、動作を確かめよ。

サンプル

[hw02.html]

<!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

2. hw02.htmlを改造して、自分で用意した画像を表示するようにする

hw02.htmlのimg要素のsrc属性を変更(上のソースの網掛けの部分)して、自分で用意した画像を評価できるように改造しよう。また、h1要素のタイトル文字なども、適切なものに書き換えよう。

この作業のコツは、hw02.htmlだけを変更すれば良いことと、どのように表示されるかを確認するためには、ローカルでhw02.htmlをブラウザで開くことで確認しながら行うことである。

hw02.htmlの修正が終わったら、hw02.htmlと自分で用意した画像ファイルをWWWサーバにアップロードして、動作を確かめよう。

【参考】PHP版

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>


戻る