アクセスカウンターです。どこのホームページにもありますが、やっぱり自分のホームページのは自分で作りたい!! とゆー方もおられることでしょう。でも結構簡単に作れちゃうんです。今日はその解説をしましょう。
あ、いくつかの関数は前回のプログラムのを使っているのでそちらも参照してください。 |
イメージカウンターの構想
今回作製するイメージカウンターの形を考えておきましょう。 まず一桁ずつ表示する形にします。すべての桁をくっつける形式は、GIFやJPEGのファイルフォーマットを知らないとできないので、不可能と考えていいでしょう。 データの保存は、ひとつのカウントデータに対してひとつのファイルにします。これはデータ構造の簡略化と、不正使用のための対策です。これだとデータの取得が簡単で、さらにデータを増やすにはデータを保存するファイルも増やす必要が出てくるので勝手に他のページで使われないようにすることができます。 様々なカウントイメージを選べるようにもします。引数にディレクトリを渡すことで、そのディレクトリの中のカウントイメージを表示するようにします。ディレクトリとイメージを増やせば様々な種類のカウンターを簡単に使えるようになります。 最後に、普通表示しない数字、例えば00512というカウントであれば、左のふたつの00は表示させないようにします。「何もなかったことにする」のは不可能なので、1ドットの透明GIFを表示させることにします。 このイメージを呼び出す時には次のようにします。 |
あなたは
<IMG SRC="Counter.cgi?KAB_Start.txt+Black+5+1">
<IMG SRC="Counter.cgi?KAB_Start.txt+Black+4">
<IMG SRC="Counter.cgi?KAB_Start.txt+Black+3">
<IMG SRC="Counter.cgi?KAB_Start.txt+Black+2">
<IMG SRC="Counter.cgi?KAB_Start.txt+Black+1">
人目のお客様です!!
第1引数のKAB_Start.txtはデータの保存されているファイルのファイル名です。このようにデータの指定はファイル名で行います。
第2引数のBlackは、画像ファイルのあるディレクトリです。Blackディレクトリには0.gifとか1.gifといった数字.gifという画像ファイルを置いておきます。このように、ディレクトリを指定することで簡単に様々なイメージを選ぶことができるようにします。 第3引数の5とか4とかは、おわかりのように桁数です。どの桁の数字を表示するかを、この引数で指定します。 第4引数の1は、増やす値です。この引数は5桁目にのみ入れてあります。全部の桁に入れたら5も増えちゃいますからね。省略すると0、つまり増やさず表示のみということにします。
ホントのことを言えば、やっぱりイメージを連結するタイプの方が理想です。ひとつひとつだと全部表示されなかったり、重くなったり、正確なカウントが表示されなかったりと、見る側にとってはストレスになります。でも、作る側としては限界があるということでこれで勘弁してください(汗)。 |
下準備
プログラムを見る前に、必要な準備について説明しておきましょう。 まず、カウンターイメージを作っておきましょう。これは別に作らなくても、フリーの画像集があるホームページがあったりするので、そういう所のを利用してもいいでしょう。もちろん、これらのファイルは、CGIのあるディレクトリに新しくディレクトリを作製し、その中に0.gif、1.gifといった形で置いておいてください。 これとは別に、CGIのおいてあるディレクトリに1ドット透明GIFを置いておいてください。ファイル名はTPDot.gifです。 カウンターデータを保存するファイルも置いておいてください。ファイル名はなんでもOK。中身が空でもOK。ただし、パーミッションを「グループ・他人でも書き込み可能」にしておいてください。chmod go+w test.txtとかすればOKです。このファイルは、カウントさせるページの数だけ作ってください。 準備はこれだけ。ではプログラムを。 |
プログラムについて
実際のプログラムはこちらです。 このリンクは新しいブラウザウィンドウを開きます。 このプログラムは著作権フリーとします。 このプログラムを使用することによるいかなる損害にも関知しません。 動作確認はリムネットだけです。他のプロバイダでは確認してません。 このプログラムを使用するときには拡張子をcにしてください。 |
引数の処理
コマンドの引数には前述したとおりに処理します。引数が3以下なら何もしません。また、「桁数」のような数字はatoi()を使ってint型にしておきます。また、第4引数(増やす数)が省略されている場合には、表示のみとして0にします。この辺に難しい部分はありませんね。 |
データの読み込み
main()の中でまず呼び出される関数はIncCount()です。この関数は、ファイルからカウントデータを取り出して返します。
ここで、まず「表示のみ(カウントを増やしません)」の場合について見てみましょう。
では次に「カウントを増やす」場合について見てみましょう。 |
シンクロナイズとファイルロック
さて、このプログラムの目玉といってもいいでしょう、ファイルロックについてです。
UNIXはマルチタスクOSです。複数のブラウザが同時に同じCGIを実行しようとした場合、ちゃんと全部実行されます。おなじCGIがふたつもみっつも並列的に同時に一緒に実行されてるわけです。
ここで、同時に実行されたCGIをプロセス1、プロセス2と呼ぶことにします。
こんな感じで、同時にファイルにアクセスする場合正確なデータが書き込まれない場合があります。これは大問題です。最悪の場合、ファイルが壊れてしまう場合もあります。複雑なフォーマットのファイルを扱う場合には特に問題となるでしょう。
プロセス1がファイルをロックします。
このように、同時にファイルにアプローチされたときにも、常にたったひとつのCGIとだけ付き合うようにすることで、ファイルが壊されないようにします。
そのための関数は2種類あってひとつはflock()、もうひとつはlockf()です。はっきり言って、どちらもほとんど同じ動作をします。どっちを使っても問題ないでしょう。
たいがいのファイル関数はFILEポインタ型を使いますが、このふたつの関数はファイルナンバーと呼ばれる物を使用します。これはファイルひとつひとつに着けられた番号のことで、ウィンドウズで言えばファイルハンドルのようなものです。この番号の取得はfileno()で行います。
次にファイルをロックします。どのファイルをロックするかはこのファイルナンバーを使用します。lockf()はちょっと面倒で、あらかじめlseek()を用いてファイルの参照位置を先頭に持ってきておきます(これはファイルポインタとはちょっと違うみたいです)。また、最後の引数の0Lは、ロックを掛ける範囲のことですが、ここでは全体にロックを掛けるので0を指定します。ちなみにLは「long型の整数だよ」ということを示すものです。
どちらのファイル関数も、ロックがすでに掛かっている場合にはその場で待ちます。ロックが解かれるとふたたびプログラムが進行します。待ちきれなくなったり、ロックに失敗したときには−1が返されるのでそれをチェックしておきます。ちなみにフラグを変えることで、待たずにすぐ返るようにもできます。
その後は前述したとおりにファイルからカウントデータを読み込み、カウントを増やしてからふたたび書き込みます。
このロック機構は、前述したとおりコンパイラによっては使えないかもしれません。そのときにはファイルを使ったミューテックスやセマフォを用いて実現する必要がありますが、これはちょっと難しいのでここでは紹介しません。こういったことや、flock()などの解説は「UNIX Network programing」という本に詳しく書かれていますのでそちらを参照してください。念のため言っておきますがむちゃくちゃ大きくて高い本です、辞書みたいです。 |
表示するイメージのファイル名の取得
IncCount()からカウント数が返されたら、今度はそれを元に表示するイメージのファイル名を取得します。これはGetCountImg()で行います。
この関数はまず、sprintf()を使ってカウント数を文字列に変換します。次にこの文字列のサイズ、つまりカウントの桁数を取得します。512なら3ということになります。
ここで表示する桁と、カウントの桁数を比較します。
「表示<=カウント」(512の時に2桁目の表示の場合など)の時には、文字列の連結を行います。 |
自分だけのカウンターを作ろう!!
このプログラムを応用すれば、いろんなタイプのカウンターが作れます。例えば一桁ごとに違うイメージディレクトリを指定して、全部継ながったときにひとつの絵になるようなカウンターだとかも作れます。もちろん時計とかも作れます。 個人的な感想ですが、あまりにも「そのホームページの雰囲気をぶちこわす」イメージカウンターが多いように感じられます。もちろんその理由の大半は、既製品を使わせてもらってるからでしょう。でも、このように自分で作製すれば、自分のホームページにカスタマイズされたカウンターを使うことができます。 ホームページの画竜点睛とも言えるアクセスカウンター、気合いを入れて作ってみませんか? |
(C)KAB-studio 1998 ALL RIGHTS RESERVED. |