8/24'97

prev next

手作りカウンター


(97.8/24)

CGI も SSI も使える

ある日、棚からぼたもちのように、CGI が使える環境が手に入った。CGI だけではない、SSI も使えるのだ。

話を進める前に関係者にお礼を言っておかなくてはならない。

ある日、ぱそ子のおかあさんから、ミラーサイト( mirror site )を作って実験をしてみませんかという話があった。当初、何の話か見当もつかなかったが、田村さんという偉い方から、人に役立つために、サーバーを使ってくれる人を探しているという。

相変らず、よく分らないが、
おかげで、CGI、SSI を使うことが出来るようになったという次第で、田村さん、ぱそ子のおかあさん、ありがとうございました。

そこで、初めに手がけたアクセスカウンター作成の経緯を発表しようとしています。

今まで、CGI をやりたいと思いながらも、ごく簡単な参考書(その分、本当に理解しようと思うと難しい)を読んだりしても、本気になれないでいたが、実際に試す環境が手に入ったとなれば、話は別である。

初めに何をするかという問題。取敢えずはカウンターもフォームデコードも利用させていただいていて不自由はしていないが、基本も知らずに他の新しいことが出来るはずもない。私も初心者である。

というわけで、カウンターを作成することから始めることに

カウンターの原理というか基本的な仕組は簡単である。また、Web裏技を始め各所にカウンターのソースや解説は発表されている。
従って、ここで取り上げるテーマはソースの公開ではなく、作成過程に見つけた問題点やアイデアなどを取り上げようと思う。

まず、初めに手にした参考書は

CGIプログラミング
:Shishir Gundavaram 著、田辺茂也 監訳、株式会社エディックス訳
:オーム社 刊
JavaScript ハンドブックと同じ、出版社、訳者のもの。

ここでも、ソース自体の誤植があったりする、内容については JavaScript ハンドブック で感じた楽しさというものはない。まあ、これは私にとって肝心なことが書かれてないという単純な理由からかもしれない。

そして、田村さんよりまず Web裏技に行くようにということで、こちらも参考にさせていただいた。

そうこうするうちに使用する言語は Perl5 ということに落ち着いた。hello.dokidoki(以降、田村さんのサーバーをこう呼ぶことにする)には、既に Perl5 はセットされていて、利用するだけでよい。

セットされているかどうかは、Telnet でサーバーに繋いで、
which perl
と打ってみればよい。

使えるようなら、/usr/bin/perl などと、Perl までのパスが表示される。
そこで、/usr/bin/perl -v のように -v オプションを付けて、Perl を起動すると、Perl のバージョンが表示される。

いよいよ、Perl が使えることが分り

クイック Perl5 リファレンス
:Micheal O Foghlu 著(正確な表記には字の上に点があったりするが)
:プレティスホール出版
というハンドブックを購入。こういう類のリファレンス本はすぐに役に立つ。

なぜカウンターか、もうひとつの理由

なぜカウンターから始めたかということについて、実はミラーサイトが出来たことがもうひとつの理由になる。

メインとミラーでそれぞれ別々にカウントされるのではなく、同じコンテンツを表示しているのだから、どちらにアクセスしても連続してカウントされるようにしたい。

そのためには、プロバイダーお仕着せのカウンターやレンタルでは、多分うまく行かない。自前で用意するしかない。

また、お仕着せのカウンターは、共用であるために重いかもしれない。そうでなくとも、汎用に作られているので、オーバーヘッドが大きく重くなるということもあるかもしれない。

制約

もともと TCP(東海インターネット) には、CGI も SSI もユーザー側では使えないという制約があった。

ミラーとなる hello.dokidoki は、SSI も CGI も使えるが、TCP 側からは、CGI しか使えない。

まあ、仮に両方のサイトで SSI が使えてもひとつのカウンターを SSI で共用することは出来ない。

SSI が使えれば カウンターの作成は格段にやさしくなるが、どうしても CGI カウンターになってしまう。

しかし、SSI を放棄する訳には行かない理由がひとつある。

通常、CGI カウンターの動作のタイミングは画像を表示した時であるが、Lynxなど、画像を表示しないブラウザでは、カウントされないのである。

通常ロボットと呼ばれるものも画像を無視するらしい。この動きも捉えてみたい。実は、このカウンターにはアクセス・ログ・ファイルも備えるのだ。

という理由で、hello.dokidoki では、SSI と CGI を併用し、TCP では CGI のみを使うことにする。その場合でも、数字を記憶するカウンターファイルは、ひとつでなければならない。

ここでまた、制約になるのがメンテナンスの関係で、カウンターを組み込む THML ファイルもまた同じファイルである必要がある。(サーバー毎に用意できない)

その後、もうひとつミラーを増やしてしまった。infonia(日本インターネットアクセス)。このサイトでは、exec 以外の SSIが使えるという。このサイトにも同じファイルを送らなければならない。ということは、hello.dokidoki のために用意した SSI ではエラーとなってしまう。

書き忘れていたが、SSI 自体に制約があった。CGI では常識のユーザーからの自由なオプションが、SSI では簡単には渡せない。

制約の解決

初めに作ったカウンターは、トップページには、SSI と CGI 用を2個所に置き、条件文で、hello.dokidoki では、SSI がカウントアップし、CGI で数字画像を表示だけするようにした。

TCP では SSI が無視され、CGI でカウントアップから数字画像の表示の両方を実行する。

他のページでは、全て CGI のみを置くという構成にした。

※ 10/26 このカウンターも現在は Hello から Infonia に移行しました。理由は、Infonia のディスク容量がいっぱいになり、追加の要請をしたところ、同時に SSI も使えるようになったということ。いつまでも借り物のサーバーに置いておくというのも問題かなと思うようになったということです。

これにより、現在の構成と以降の説明では、少し異なるところがあります。

SSI についてはテキストで数字の表示が出来るので、全く問題ないが、CGI の方は、バラバラの数字画像をひとつにして表示するという方法が分らないので、当初、同じ CGI カウンタープログラムを、表示したい桁数分、並べて、各桁毎に数字画像をひとつづつ表示するという方法を採った。

最上位の桁にある CGI が、カウントアップして他の桁は表示するだけとした。通常のプログラムであれば、最も左にある最上位桁の CGI が初めに動作、カウントアップし、次々に結果の画像を表示すると思っていたら、CGI の動作順序は、全く不定であることが分った。

これでは、表示される数字が正しいこともあるが、不正の方が確率が高いことになる。

これは、画像をひとつにする以外に解決の方法はない

ここで、CGI と SSI の違いについて見ていくと、CGI は Common Gateway Interface ということで、私の理解の範囲では、ブラウザとサーバーとやり取りするインターフェースということになる。

一方、SSI も似たようなイメージがあるが、SSI の I はインターフェースではない。Server Side Include ということで、直訳するとサーバー側で内包(?)。どうやら、サーバー内でのサービスといったところだろうか。

要するに、似ていても全く違う性質を持っている。

実際の動作では、CGI は、

  1. フォームなどの応用で、HTML ファイルを作り出す。
  2. イメージタグを使って プログラムを動作させ画像を表示する。
  3. count.cgi?ketasu=5;bgcolor=CC... という書式で、さまざまなオプションをプログラムに渡すことが出来る。( ? 以下がプログラムに渡すオプション)
というのが、主な動作になる。
つまり、現在表示されている HTML ファイルの中に埋め込めるのは、画像だけであり、テキストを埋め込むことは出来ない。そのように見えるのは、CGI プログラムから吐出されたダイナミック HTML に置換えられている(HTML ファイルを作り出す)時である。

対して、SSI は、

  1. これから表示される HTML ファイルの中にテキストを埋め込むことができる。
  2. 画像は直接には出来ないのだが、イメージタグ(テキスト)を埋め込むことで、間接的に画像を表示させることが出来る。
  3. CGI では、簡単に渡せるオプションが、SSI では難しい。フレームを応用することで、辛うじて渡すことが出来るということだが・・・。CGI に付いている ?ketasu=5;bgcolor=CC... などを付けたら、SSI は動作しなくなる。
一応、このように理解出来れば、 SSI で、カウンターを作ることは非常に簡単だということが分る。

ただし、箇条書きの 3 番目の理由で、ひとつのカウンタープログラムで複数のページにカウンターをばらまくことは難しい

※ 99.11
当初 count.cgi?ketasu=5&bgcolor=CC... としていたが、オプションの区切りは & でなく、; とするのが正しいようです。

私のホームページでも、hello.dokodoki の表紙以外では、SSI カウンターは置いていない。( hello.dokidoki のサイト内であれば、置きたいページ毎にそれぞれのカウンタープログラムを作れば可能だが。)

実際、SSI用のカウンターはすぐに出来てしまう。Web裏技にも、超初心者の為の「超シンプルなアクセスカウンターの作り方」というのが紹介されている。私が1年前に試して失敗したものである。要するに、この時は SSI が使えないサーバーであったということ。もちろん、CGI も使えなかった。

数字画像の表示で行き詰まっていた。まだ CGI でテキストが HTML に埋め込めるかもしれないというかすかな期待がある頃、Hirさんのカウンターがテキストで実現していた。

これは、SSI で実現しているに違いないと思い込んでいたのだが、Hirさんによると SSI は使えないサーバーなので、CGI で実現しているという。

フレームを使って CGI から、数字のテキストを埋め込んだ html ファイルを吐出すという方法は、この頃でも分っていたが、Hirさんのトップページにはフレームを使っていないことも分っていた。・・・MSIE 2.0 でも表示できるのだ・・・

一体どうやって実現したのだろう。もしかして、やはり、html にテキストを埋め込めるのだろうか。

とうとう、観念して、教えを請うことにした。Hirさんからは、ソースを含め詳しい説明をいただいた。確かに、トリッキーで面白い方法であったが、フレームを使った方法と同じく、ミラーを維持するという観点では、不向きな方法であったのは残念であった。

数字画像を使わなくてすむ、そのトリッキーな方法とは、簡単に説明すると、イメージタグから CGI のカウントファイルをインクリメント(数字をひとつ増加)して、その数字を埋め込んだ HTML ファイルを生成してファイルに保存する。

このファイルを次の人が読み込むことになる。この時には、既にカウントアップした数字は埋め込まれているので、表示も速いし、一見 SSI のように見える。

このタイミングで、イメージタグから次の人のために htmlファイルを生成するという循環になるというものだ。

Hirさん、その面白い方法と詳しい説明ありがとうございました。

ここで、ひとつ覚えたことは既存の HTML ファイルを読み込んで、その指定した個所にテキスト(この場合数字のテキスト)を埋め込むことが出来るということだ。

CGI を動作させるイメージタグは HTML ファイル内のどこにあってもよい。

似たような方法で、Perl などのプログラムの print 文で、HTML ファイルを生成するという方法(フォームでよく使うようだ)は知っていたが、少しばかり意味合いが違う。

結局、数字画像での表示ということに戻ってしまった

画像で表示するからには、バラバラの数字画像をひとつにする方法を採らなくてはならない。

※ 既に画像をひとつにしたカウンターが出来た後で、バラバラの画像で正しい数字を表示するカウンターがあることが分った。

これは私の採用した方法とは逆に計算を最後の画像で行うという方法。

前のアクセスでカウントアップした数字を画像表示して、最後尾の桁の数字が表示された後、次の人のために数字をカウントアップして保存するというもの。
(この部分は前出のHirさんの考え方と同じですね。)

これを成功させているのは、計算を省いて初めに画像表示に専念した後、最後にカウントアップしていることと、さらに最後の桁を表示する前にウェイトを置いているということのようです。

参考書の 「CGIプログラミング」には、Gif イメージを作り出す方法として、GhostScriptGD の例が載っている。
 これらは、予め Gif ファイルがなくても、プログラムにより、Gif イメージを作り出すことができる。文字の出力も予め用意されているフォントにより、テキストを表示するように、Gif イメージとして作成する方法が載っていた。

既存の Gif ファイルからコピーする事も出来るが、この方法は例題に載っていない。

GS( GhostScript )は、非常に豊富な機能を持っているということであるが、多くのシステムリーソースを消費するということで、GD の方に興味を持った。
参考:http://www.phys.ufl.edu/docs/goodies/unix/previewers/ghostscript.html

システムリソース不足は、Windows95 になっても悩みの種である

GD は、GS 程の機能はないものの迅速かつ簡単にダイナミックイメージが作成できるとある。
参考:http://www-genome.wi.mit.edu/ftp/distribution/software/WWW/GD.html

その他に、田村さんを通じて mkstrip というのも紹介されたが、私にはちょっと難しかった。
参考:http://www.fccc.edu/users/muquit/Count.html

GD をダウンロードしたものの今度はインストールで引っかかってしまった。Perl 用の圧縮ファイルを解凍すると、Readme やら C言語のソースといったテキストファイルが、ディレクトリ付きで展開されるが、これをどうしたらよいやら分らない。

最終的には C言語がコンパイルされて、バイナリーファイルが出来上がらなくては使い物にならないのだろうが、どうすればよいのか。

こんな状況をきよママさんに一言伝えると、きよママさんより Fly のリンク先を紹介してくれた。

Fly といえば、既に Web 裏技で、存在は知っていたが、この時は、SunOS4 でしか使えないと思い込んでいた。

とにかく、紹介されたhttp://www.unimelb.edu.au/fly/fly.htmlに飛んでみると、Fly の概要、使い方、インストールの仕方が簡潔に書かれていた。

よく読むと、SunOS4 に限らず、実行する環境下でコンパイルすることで、いろいろな OS に対応することも分った。

結局のところ、この Fly で、私のカウンターは完成することになる

既に、Fly があることは、Web 裏技で知ってはいたが、私の勘違いで見向きもしないでいたものがきよママさんのタイミングよいアドバイスで復活したという感じ。ありがとうございました。

Fly は、インストールから Script の書き方まで、非常に分かりやすい。まず、コンパイル済みの SunOS 用を始め、Linux 用など、いくつががバイナリーで用意されている。

もしない場合でも、実行環境下でコンパイルすればバイナリーが生成される圧縮ファイルがいくつかのタイプで用意されている。私は Windows内でも解凍できる pkzip 版をダウンロードした。

展開すると fly-1.4.2 というディレクトリと共にその下にいくつかのファイルが出来上がる。このディレクトリの下には、gd1.2 というディレクトリも作成されている。

何の事はない、Fly 自体が GD のモジュールを利用しているのだ。とにかく、これをディレクトリ毎、サーバーに送り、Telnet でそのディレクトリに入り make と打ち込むだけで、GD の C 言語のライブラリを取り込んで、Fly のバイナリーファイルが生成されるのだ。

もし、うまく行かない場合には、Makefile 内の CC = gcc という行を CC=cc に書き換えてみるようにというトラブルシューティングもある。

これを書き換えることもなく、コンパイルが出来たが、初めてのリモートでのコンパイルだったので、実際にテストが終わるまで、半信半疑であった。

うまく行っていることが分った時点で、実に簡単に使えるようになっていることを改めて認識した。

ここで、ちょっとカウンターのソース

たぶん、Web 裏技から入ったのだろう、参考書もまだない時に勝手にPerlリファレンスというサイトに飛んだ。

ここの「勝手に Perl Tips」にビジュアルアクセスカウンターを作るがあった。

このソースを見て、これなら私にもすぐにも作れると思ってしまったのが運の尽きであった。

ここに書かれていたソースは SSI 用のものであったのだ。

カウンタファイルを開いて、それをインクリメントして、書き戻すという動作は、SSI であろうと CGI であろうと変らない。

open(COUNT,"count");	# count をオープンして。
 || die "Can't Open COUNT: $!\n";# オープンできなければコメントを表示して終了
$num = <COUNT>;	# 変数 $num に count の数字を代入する
close(COUNT);		# クローズ
open(COUNT,">count");	# 書込み属性で count をオープン
 || die "Can't Open COUNT: $!\n";
$num++;			# 変数 $num を1繰り上げる(インクリメント)
close(COUNT);		# クローズ

※カウントアップの部分のみ抜粋。コメントは独自に付けさせていただきました。

以上で、このカウンタの心臓部は動作する。実際には、ロック式といって、めったに起る事はないが、ほぼ同時に count ファイルがオープンされると、その count ファイルが消えてしまうという事態から保護するための処理を加えた方がよい。

open から始る行と || から始る行は1行でよいのだが、幅を狭めるために、2行に分けたが、どちらでも動作する。Perl や C では、プログラムから見ると ; が現れるまでは1行と見なされる。

問題は、次の数字画像表示の部分

$i = 5;			# 表示桁数を設定
$num_a = $num;		# 上でインクリメントされた数字を代入
until ($i < 0){	# $i回繰り返す
	$j = int($num_a / (10 ** $i));	# 最上位桁の数字を$jに代入
	print "<IMG SRC=\"$j.gif\">";	# イメージタグを出力
	$num_a -= ($j * (10 ** $i));	# 最上位桁を取り去る
	$i--;		# $iをデクリメント(1を引く)
}
※これもコメントを独自に付けさせていただきました。

これで Perl を使えば、CGI でも数字画像を表示できると思ってしまったことだ

もちろん、SSI では、問題ないのだが。

実際に動作されるためには、前準備は必要だ。表示する数字の画像、CGI を置くディレクトリと count ファイルのパーミッション変更、等々・・・。

※詳しくは、上記リンクを参考のこと。

この SSI が実行され、1000をゲットすると、SSI を埋め込んだ部分に、

<IMG SRC=1.gif><IMG SRC=0.gif><IMG SRC=0.gif><IMG SRC=0.gif>
が出力され、結果 1000 のイメージ画像が表示される。

簡単でしょう。さらに、SSI で数字を出力するだけなら、この部分は、

print $num; # カウンターの数字の入った変数を表示
これだけ!!

この数字の出力を CGI で実現する為には

(ここからは、FLY のマニュアルを参考にしています。)

$font_gap = 2;			# 数字画像間の開き(なくてもよい)
$font_width = 32+$font_gap;	# ここでは数字画像の幅を32ピクセルに固定している
$font_height = 32;		# 同じく高さを32ピクセルに
$count_length = length($no_visitors);	# カウンターの桁数を取得
$img_width = ( $font_width * $count_length - $font_gap ); # 表示されるカウンター画像の幅を計算。
$insert_width = 0;		# 一つ目の画像が置かれる X 座標

print "Content-type: image/gif", "\n\n"; # CGI で画像表示する時の決まり文句(表示タイプを指定)

$image_dir = "./images/$num_dir"; # 画像が置かれたディレクトリ(この場合変数で指定)
$flyprog = "./fly";		# フライ(採用した画像表示用のプログラム)の場所を指定
$infile = "/tmp/fly.$$";	# 一時ファイルを指定
# fly の例文でも、こうなっているが、エラーで、一時ファイルが残っても
# ルートになるので処理できない。そこで $infile = "../tmp/fly.$$"; のように
# tmp ディレクトリを自分のパーミッションの及ぶ範囲に作成した方がよいのでは。
# この時、tmp には、読み書き属性を設定する。

# 以降、表示する画像を作り出す。

open(FLY, ">$infile");
print FLY "new\n";
print FLY "size $img_width,$font_height\n"; # 画像のサイズ指定
print FLY "fill 1,1,204,204,204\n";	# 背景をグレーに塗る

# 以降、上で作った画像に、カウント数字に応じた数字画像をコピーする

$i = 0;
while( $i < $count_length ) {
	$num = substr($no_visitors, $i, 1); # 各桁の数字を取得
	print FLY "copy $insert_width,0,-1,-1,-1,-1,$image_dir/$num\.gif\n";
	$insert_width = ($insert_width + $font_width);
	$i++;
}

print FLY "transparent 204,204,204\n"; # 204で表示されるグレーを透過色に指定
close(FLY);

# ここで、やっと画像の表示

open(FOO,"$flyprog -q -i $infile |");
while( <FOO> ) {print;}
close(FOO);

unlink($infile);

※以上は、Fly のマニュアルを頼りに作り上げた画像表示部分のソースです。
※変数名が冗長に見えるかも知れないが、こうする事によりコメントを省略できます。実際のソースにはほとんどコメントはない。

SSI に比べると、CGI で数字画像を表示するのは、大分難しいことが分るでしょう。もちろん、この前に Fly が使えるようにインストールする必要がある。

※ 10/26 実は当初、ソースの最後の行 unlink($infile); を書き忘れていました。実際のプログラムでも忘れていました。 このためとんでもないことになってしまいました。

ソースの初めに $infile = "/tmp/fly.$$"; がありますが、これは自分の管理できるディレクトリよりも上の tmp というディレクトリに FLY が作る一時ファイルを生成することを意味します。

当初、FLY が作るファイルなので FLY が勝手に消去すると思い込んでいました。気がつくまでの間アクセスがある度に一時ファイルがどんどん増殖していたのです。
実は実際にサーバーダウンがあって、オーナーの田村さんより一時ファイルを消すようにしてくださいという連絡があった時点でも、その原因が分っていなかったのです。
FLY の例題を見ると、ちゃんとこの1行がありました。
こうした場合、国外のサーバーでは訴訟に発展することもあるとか聞く。Infonia の説明には障害を起こすプログラムは無断で削除するとあります。

こんなことがあっても、田村さんからは励ましの言葉まで戴いてしまいました。

教訓:気を付けるべきは無限ループだけではない。一時ファイルの始末は自分でする。

Fly について、ちょっと。

http://www.unimelb.edu.au/fly/fly.htmlには、Fly が正常に動作するかを試すサンプルが載っている。

サンプルをコピーして、ディレクトリの指定など環境の違う部分を注意深く変更して、この CGI プログラムを転送。テスト用の HTMLファイルも転送する。

いざ実行すると、そう簡単には動いてくれない。しかし、その全ては記入上のケアレスミスであった。そうこうして「にこにこマーク」のサンプル画像が表示された時は感動!!

やっと、無事に Fly がコンパイルされている事が実証された。サンプルには画像のコピー( copy )はないが、書式には

copy x,y,x1,y1,x2,y2,filename.gif
     Copies region x1,y1 - x2,y2 of filename.gif to the coordinates x,y of the image
     being created/modified.
     If x1,y1,x2,y2 are all -1, copy the entire image.
とある。

前出の GS の座標原点は参考書によると、イメージの左下が(0,0)であるが、Fly や GD は、左上が原点になる。GS は通常のグラフの作りやすさを意識しているのであろう。しかし、通常の画像の原点が左上であることから、Fly や GD の方が、私には分かりやすい。
にこにこマーク」を表示する代わりに

print FLY "copy 0,0,-1,-1,-1,-1,$image_dir/9.gif\n";
に置換えて、実行。画像「9」は表示されない。おや!

ここでは、既に使われている画像数字「9」が表示される筈であった。
文法に間違いはない筈だ。試しに、表示を「MAIL」の画像に置換えてみた。すると、どうだ!ちゃんと表示されている。

両者の画像の違いを比べてみた。「MAIL」は4ビットの16色、「9」は2ビットの4色画像で作成されている。画像の色数が関係しているだろうか。

ここでまいるさんとの以前(5月頃)のやり取りを思い出した。カウンターを用意したプロバイダの指定通りに設定しているのにカウンターの画像が表示されないという。この時は、画像を置くディレクトリの場所とかパーミッションの設定の間違いとか思っていた。
実は、プロバイダからマルチ GIF は使えない、即ち「透過 GIF」は使えないという連絡で見事解決。

そうなのだ。透過 GIF は使えない

そこで、PaintShopPro で、透過属性を削除。ところが、まだ駄目であった。GIF には、PaintShopPro によると、89a と 87a という2つのバージョンがある。透過にするには 89a でなくてはならないが、このバージョンのまま「透過情報を保存しない」を選んだのであるが、これではいけない。

しかも、PaintShopPro では、4色画像で保存できない。D-Pixed なら4色で保存できる。もともと、私の数字画像は、D-Pixd で作成していた。

では、ということで、これを、D-Pixdで4色指定して透明化 GIF のチェックを外して保存する。見事、数字画像は表示された!

もちろん、透過の設定は、Flyで行う。

transparent R,G,B
     Makes the colour R,G,B the transparent colour.

exec の使えない SSI

表紙の HTML ファイルは、どのサイトも同じファイルを転送している。TCP は、SSI が使えないから無視されるだけだが、infonia では、exec 以外は使えるという。
 exec 以外は使えるとは、どういうことか。
SSI の書式は
<!--#command option="..."-->
となる。

この #command に、#exec が使えないということで、本来、<!--#exec cmd="xxx.cgi"--> で実行される筈の CGI が実行できないということになる。

私のカウンターの場合、実行できないのはいいのだが、必ず an error occurred .... と表示されてしまう。ちょっと見苦しい!

ここで、ちょっと古い「ワンランク上のホームページのための HTML&CGI 入門」が登場する。ここには、このエラーメッセージを変更する方法が書かれている。
<!--#config errmsg="Here's infonia."-->
を、<!--#exec cmd="xxx.cgi"--> より以前に置いておけば、<!--#exec cmd="xxx.cgi"--> で表示されるエラー表示の代わりに Here's infonia.と表示される。

問題は、hello.dokidoki でエラーが起きても、Here's infonia. と表示されることになる。
エラーが起きないことを祈る!!

SSI と CGI の使い分け

hello.dokidoki 以外は、SSI のカウンターは動作しないので、CGI 側のカウンターは常に動作してよいが、hello.dokidoki は、SSI がカウントアップ動作をするので、CGI の方は動作しないように、条件付けが必要になる。
 hello.dokidoki か、そうでないかの判定は、そのカウンターがどのファイルに置かれているかで判断する。

ファイルの判定には HTTP_REFERER という環境変数を使う。
Perl では
$url = $ENV{'HTTP_REFERER'};
の1行で、$url という変数に、カウンターを置いたファイルの URL が代入される。

ただ、この HTTP_REFERER は、特に癖があって、正しい結果を返さないことがある。幸いなことに、独自に調査した結果では CGI のカウンターでは、どのサイトにあっても 100% 正しい結果を示した。それが、SSI カウンターでは、状況により全く異なる結果となる。空白であったり、ゲストブックなどから飛んできたリンク元の URL を示したりした。

hello.dokidoki 上の SSI カウンターは無条件に動作させるので、HTTP_REFERER の結果はどうでもよい。一方、CGI カウンターの方は、SSI で、既にカウントアップされているので、カウントをせずに、SSI でカウントされた結果を表示するだけにする。

偶然にも、hello.dokidoki の URL には、/~yoshi が、他は、/~yosi が含まれることになる。
http://hello.dokidoki.ne.jp/~yoshi/xxxx.html

この yoshi を切り出して、比較すれば、条件式は出来上がる。

Perl には、強力な文字列操作関数がある。

# ---------------------------------
$url = $ENV{'HTTP_REFERER'};

# 1.これで、余分な http:// は切り離しできる。
#   実際には // の前後の文字列に分割するという動作をする。

($dumm1,$url) = split(/\/\//, $url, 2);

# 2.これで、~ 以前の文字は切り離される。

($dumm2,$yosi) = split(/\~/, $url, 2);

# 3.これで、yosi または yoshi のみの切り出しが出来る。

($yosi,$dumm) = split(/\//, $yosi, 2);
# ---------------------------------
※ yoshi のきり出しということでは、1.は、余分な操作。2.と 3.により、切り出される。
あとは、$yosi が、yoshi であるか、yosi であるかで判定する。

最後に、CGI で最も簡単に画像数字を表示する方法

これは、一見、テキストを表示しているように見える。

$font_width = 7;	# Flyが用意しているフォントの幅
$font_height = 14;	# 同じく、フォントの高さ。( medium )
$count_length = length($no_visitors);
$img_width = ( $font_width * $count_length );

print "Content-type: image/gif", "\n\n";

$flyprog = "./fly";
$infile = "/tmp/fly.$$";

open(FLY, ">$infile");
print FLY "new\n";
print FLY "size $img_width,$font_height\n"; # イメージの範囲を設定
print FLY "fill 1,1,204,204,204\n";

# medium フォントで、$no_visitors(カウンターの数字)を配置
print FLY "string 0,102,204,0,0,medium,$no_visitors\n";

print FLY "transparent 204,204,204\n";
close(FLY);

open(FOO,"$flyprog -q -i $infile |");
while( <FOO> ) {print;}
close(FOO);

unlink($infile); # FLY の生成する一時ファイルを削除。忘れないように!


消化不良と思われる方もいるかも知れませんが、一旦、ここまでとします。なお、既に執筆した内容を予告なく変更する場合があります。


prev

To MENU

メインメニューへ