SSIアクセスカウンタ

Perlでプログラミングを始める前に、プログラミングの作成環境と実行環境が必要となる。まず、プログラムソースを書くために、テキストエディタが必要である。これはメモ帳やWordパッド、ワープロソフトでもよい。文章以外の情報をもたないプレーンテキストで保存できればよい。

Perlのプログラムは、Webサーバーへ転送し、Webサーバー上でプログラムを実行する。このためWebサーバー上にPerlの実行環境を作らなければならない。これはレンタルサーバーやプロバイダーによって違うので、レンタルサーバーやプロバイダーのマニュアルを参照して欲しい。

アクセスカウンターのプログラムの流れを考える

「アクセスカウンター」は、Webサイトにアクセスすると、その回数をカウントして表示するものである。プログラミングの前にアクセスカウンターの処理の流れを考えてみよう。

まず、数を数えていくので、今現在まで何回アクセスされたかを憶えておく必要がる。そのために数を記録するためのファイルが必要になる。普段ワープロなどで作成した文章を、また使うために保存しておくのと同じである。継続して使用する情報はファイルに書き出すことで、プログラムの実行が終わってもデータが消えずに残るようになる。

プログラムが実行されたら、ファイルに記録された前回までのアクセス数を取り出す。そして、その数に1を足して、表示させる。更新したアクセス数をファイルに保存する。この手順のがアクセスカウンターのプログラムの流れである。これをPerlで書くと以下のようになる。

#!/usr/bin/perl #SSI カウンター if ( !open(DAT,"+< count.dat") ){ if ( !open(DAT,"> count.dat") ){ print "file open error";exit; } } flock(DAT,2); $cnt=<DAT>; $cnt++; seek(DAT,0,0); print DAT $cnt; flock(DAT,8); close(DAT); print "$cnt";

プログラムの説明

では、各行の内容を順に見ていこう。

#!/usr/bin/perl
#SSI カウンター

#!に続くパスは、Perlがどこにあるかを指定していまる。この部分は実行する環境によって異なるので、確認して適宜変更して欲しい。

「#SSIカウンター」の部分はコメントである。Perlでは先頭に「#」がつく行は、コメントとして認識され、プログラムの実行に影響を与えない。

次からがプログラムの部分になる。Perlでは1命令の終わりに;(セミコロン)を書かなければならない。

if ( !open(DAT,"+< count.dat") ){ if ( !open(DAT,"> count.dat") ){ print "file open error";exit; } } flock(DAT,2);

この部分が「ファイルを開く」処理である。ファイルにデータを書き込んだり、読み出す場合は、操作の対象となるファイルを指定し、ファイルを開かなければならない。その命令がopenである。

open(DAT,"+< count.dat")

これで「count.dat」というファイルにアクセスできるようになる。DATというのは「ファイルハンドル」と呼ばれるのもで、ファイルへの操作を行う命令を書くときには、このファイルハンドルでどのファイルが対象になるかを指定する。DATでなくても、好きな名前を付けてかまわない。意味が分かりやすい名前にしておくとよいだろう。

「"+< count.dat"」は、ファイル名とファイルへの操作の内容を指定している。この場合、count.datと言うファイルに対して操作を行う、と言うことである。+<は、ファイルに対して読み込みと書き込みの操作を行うことを意味している。この部分で、ファイルを操作する準備が完了している。

open命令がifと言う命令にカッコで囲まれているが、これはファイルが正しくオープンできたかどうかを確認している。ファイルが存在していなかった場合など、ファイルがオープンできなかった場合()、{}の中の処理が実行される。!が無い時は、正しくオープンできたとき、ということになる。

2つ目のopen命令は、このプログラムが第一回目に実行されるときのためのものです。初めての実行なので、前回のカウント数というものはない。当然count.datというファイルも存在していない。この場合、一つ目のopen命令は読み書きモードでファイルを開こうとしているので、ifのチェックに引っかかる。

そして、2つ目のopenが実行される。ここでは「書き込みのみ」でファイルを開くように指示している。この時に、ファイルが存在していなければ、新たに指定されたファイルが作られる。それでもファイルを開くことができなかった場合は3行目が実行される。

print "file open error"exit;

エラーメッセージを表示して、ここで強制的に終了する。通常はこの部分が実行されることはまずないだろう。

これでファイルに対して操作を行えるようになった。しかし、これでは不十分である。Web上で動くプログラムは、同時にたくさんの人から実行されることがある。しかし、プログラムが使うファイルは1つだけである。1つのファイルに別の人から同時に読み書きされた場合、内容が壊れてしまうことがある。これを防ぐためにファイルをオープンしたら、別の人が開けないようにロックをかける必要がある。

flock(DAT,2);

これでロックを解除するまで、ほかからはアクセスできない。ロックするファイルをファイルハンドルで指定する。2は、このファイルに書き込みを行うので、ほかの人は読んだり書いたりさせない、という指示である。

では、ファイルからデータを取り出す。

$cnt=<DAT>; $cnt++;

$cntにファイルの情報が移される。$cntは変数である。変数とはデータを保存しておくための入れ物である。$の後ろは好きな名前を付けてかまわない。

$cnt=<DAT>;

DATからデータが一つ取り出されて、$cntに入る。数学の数式として見ると、変な式だが、これは「右辺の内容を左辺へ入れる」と理解して欲しい。

これで今、$cntには前回までのアクセス数が入っていることになる。これに1を足した数が、Webページ上に表示されるカウント数になる。

$cnt++;

これで、$cntの内容が1足される。$cnt=$cnt+1と同じ意味である。1つだけ増える場合は、縮めて書くことができる。

seek(DAT,0,0); print DAT $cnt;

カウントアップの処理が終わったので、この結果を保存する。データを書き出す前に、ファイルのどの位置に書き出すかを指定する。先ほどデータを取り出したので、ファイルハンドルは取り出したデータの次の位置を指している。つまり、ファイルの終わりを指している。書き出す前にファイルハンドルをファイルの先頭に戻してやる。

seek(DAT,0,0);

0,0はファイルの先頭から、0バイト目という意味である。つまりファイルの先頭である。

print DAT $cnt;

print命令でファイルに出力する。ファイルハンドルに続けて、出力する内容を書く。

flock(DAT,8); close(DAT);

ファイルへの記録が完了したら、プログラムの後始末である。ファイルのロックを解除する。

flock(DAT,8);

8は解除の指示である。

close(DAT);

close命令でファイルの使用が終わったことを明示する。

print "$cnt"

最後にカウントした数字を、Webページ上に出力する。今度はファイルハンドルを指定していない。ファイルハンドルが書かれていない場合は、「標準出力」というところへ出力される。この場合、printの内容はSSIの実行指示が書いてある部分に挿入される。

ダブルクォテーション(””)でくくっているが、$cntしか書いていないので省略してもかまわない。

print "アクセス数は$cntです";

こういう場合は、"でくくる。

Google