- ベストアンサー
昨日と今日のカウンタについて ご指摘下さい
- 昨日と今日のカウンタについて、カウンターが1こずつではなく、4つとか5つとかずつ増えてしまいます。
- html内の<p>本日の数は<img src="./count.cgi?today">です</p><p>昨日の数は<img src="./count.cgi?yeaday">です</p>を削除すると、ちゃんと1つずつカウントしていきます。
- プログラムのどこが間違っているのでしょうか?アドバイスをお願い申し上げます。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
> 例えば、ログでは26なのに表示は25のまま。更新するとログは27で表示も27。ログはきちんとカウント > されているみたいですが、HTMLの表示の方が突然2つ増えてしまうという現象が発生します。 「ログでは26なのに表示は25のまま」は画像を送り出した後に $today をインクリメントしていることを示し、 「更新するとログは27で表示も27」は $today をインクリメントした後に画像を送り出していることを示して いると思います。本日のカウント数が正確なのは、count.html?total から呼び出された CGI 内で $count を インクリメントした直後に画像を送り出しているからです。本日のカウント数も同じように、count.html?today から呼び出された CGI 内で $today をインクリメントして画像を送るようにすればすれば直るはずです。 gifcat.pl と gifcat() 関数について私にはわかりませんが、次のプログラムは直すことなくこのままで (たぶん) 実行できると思いますので試してみてください。 #!C:\Perl\bin\perl $ENV{'TZ'} = "JST-9"; require "./gifcat.pl"; $mday = (localtime(time))[3]; open (FILE, "<logday.dat") || die "File Open Err!-logday.dat\n"; chomp($logday = <FILE>); close(FILE); ($day, $count, $today, $yesday) = split(/:/, $logday); if ($ENV{QUERY_STRING} =~ /total/) { ++$count; open (FILE, ">logday.dat") || die "File Open Err!-logday.dat\n"; flock(FILE,2); print FILE "$day:$count:$today:$yesday\n"; flock(FILE,8); close(FILE); &img_send($count); } elsif ($ENV{QUERY_STRING} =~ /today/) { if ($mday != $day) { $yesday = $today; $today = 0; } ++$today; open (FILE, ">logday.dat") || die "File Open Err!-logday.dat\n"; flock(FILE,2); print FILE "$mday:$count:$today:$yesday\n"; flock(FILE,8); close(FILE); &img_send($today); } else { &img_send($yesday); } sub img_send { @num = split(//, $_[0]); foreach $num (@num) { push(@view, "./img-d/$num.gif"); } print "Content-type:image/gif\n\n"; binmode(STDOUT); print &gifcat::gifcat(@view); }
その他の回答 (3)
- kumoz
- ベストアンサー率64% (120/185)
$today が狂うのは、count.html の画像のロード順 (count.cgi の実行順) が一定でないのが 原因かもしれません。毎回 total → today の順番で実行されると問題ないのですが、ときどき today → total の順番で実行されると、その場合は $today が前と同じだったり、2増えたり します。これを解消するには、total と today を別々にカウントする必要があります。 #!C:\Perl\bin\perl $ENV{'TZ'} = "JST-9"; $mday = (localtime(time))[3]; open (FILE, "<logday.dat") || die "File Open Err!-logday.dat\n"; chomp($logday = <FILE>); close(FILE); ($day, $count, $today, $yesday) = split(/:/, $logday); if ($ENV{QUERY_STRING} =~ /total/) { ++$count; open (FILE, ">logday.dat") || die "File Open Err!-logday.dat\n"; flock(FILE,2); print FILE "$day:$count:$today:$yesday\n"; flock(FILE,8); close(FILE); &total(); } elsif ($ENV{QUERY_STRING} =~ /today/) { if ($mday != $day) { $yesday = $today; $today = 0; } ++$today; open (FILE, ">logday.dat") || die "File Open Err!-logday.dat\n"; flock(FILE,2); print FILE "$mday:$count:$today:$yesday\n"; flock(FILE,8); close(FILE); &today(); } else { &yestaday(); } sub total { ... } sub today { ... } sub yestaday { ... }
補足
何度も教えて頂いて誠にありがとうございます。 ですが、本日のカウントだけやはり正常に動かないみたいです。例えば、ログでは26なのに表示は25のまま。更新するとログは27で表示も27。ログはきちんとカウントされているみたいですが、HTMLの表示の方が突然2つ増えてしまうという現象が発生します。段々カウンタらしくなってきたのですが、この現象を回避するには、何をすればよいのでしょうか?再度お知恵をおかし下さい。よろしくお願い申し上げます。
- kumoz
- ベストアンサー率64% (120/185)
ファイルの読み書きに関して、いくつか問題があるようです。 > sub totalcount{ > open(FILE, "+<count.dat") || die "File Open Error!\n"; > flock(FILE,2); > > $count++; #トータルカウント数にプラス1 > $today++; #同じく本日のカウント数にもプラス1 > > seek(FILE, 0, 0); > print FILE "$count\:$today"; > > flock(FILE,8); > close(FILE); > } 上記の書き込み方では、$today のデータが狂うときがあります。例えば、現在 1234:56 が書き込まれていて、翌日になったため 1235:1 を書き込んだ場合、$today は 16 に なってしまいます。ファイルを切り詰めて書き込むこともできますが、この場合読み 込みは行っていないので、他のところと同じように書き込みモードでファイルを開い てはどうでしょうか。 open(FILE, ">count.dat") || die "File Open Error!\n"; ... print FILE "$count:$today\n"; もう1つの問題は、ファイルの書き込みの際に改行が書き込まれいないことです。 通常、ファイルの読み込みは行単位に行われ改行を目印に読み込まれます。次の ようにすることをお勧めします。 open (FILE, "<count.dat") || die "File Open Err!-logday.dat\n"; chomp($logday = <FILE>); close FILE; ... open (FILE, ">count.dat") || die "File Open Err!-logday.dat\n"; flock(FILE,2); print FILE "$count\:$today\n";
補足
親切丁寧にお教え頂き誠にありがとうございます。 ですが、すみません。改善されませんでした。相変わらず本日のカウンタがおかしいです。私の記述ミスだと思うのですが、何処が悪いかもう一度指摘して頂いても良いでしょうか? 以下、お2人のご指摘の元修正したプログラムソースです。 <<count.cgi>> #!C:\Perl\bin\perl $ENV{'TZ'} = "JST-9"; $mday = (localtime(time))[3]; open (FILE, "<logday.dat") || die "File Open Err!-logday.dat\n"; chomp($logday = <FILE>); close(FILE); ($day, $yesday) = split(/:/, $logday); #それぞれ、今日の日付、昨日のカウント数に分ける open(FILE,"<count.dat") || die "File Open Error!-count.dat\n"; chomp($count = <FILE>); close(FILE); ($count, $today) = split(/:/, $count); #それぞれ、トータルカウント数、今日の日付のカウント数に分ける # 数をカウント================ $mode = $ENV{'QUERY_STRING'}; $mode =~ s/\W//g; if($day == $mday){ #同日だったなら、トータルと本日のカウントだけ取る。 &totalcount() if $ENV{QUERY_STRING} =~ /total/; }else{ #違っていたら、本日のカウント数を昨日へ、本日のカウントを0に、日にちを修正 $yesday = $today; $today = 0; open (FILE, ">count.dat") || die "File Open Err!-count.dat\n"; #本日が0になったので記録を修正 flock(FILE,2); print FILE "$count\:$today\n"; flock(FILE,8); close(FILE); open (FILE, ">logday.dat") || die "File Open Err!-logday.dat\n"; #日付と昨日のカウントの記録を修正 flock(FILE,2); print FILE "$mday\:$yesday\n"; flock(FILE,8); close(FILE); &totalcount() if $ENV{QUERY_STRING} =~ /total/; #その後カウントをとる } require "./gifcat.pl"; #画像表示のif文================ if($mode eq "total"){ &total(); }elsif($mode eq "today"){ &today(); }else{ &yestaday();} exit; # ログの更新================================ sub totalcount{ open(FILE, ">count.dat") || die "File Open Error!\n"; flock(FILE,2); $count++; #トータルカウント数にプラス1 $today++; #同じく本日のカウント数にもプラス1 seek(FILE, 0, 0); print FILE "$count\:$today\n"; flock(FILE,8); close(FILE); } # カウンタの数字に画像を付ける sub total{ #トータルカウンタ============= @countdata = split(//, $count); foreach $cou(@countdata){ push(@view, "./img-t/$cou.gif"); } print "Content-type:image/gif\n\n"; binmode(STDOUT); print &gifcat::gifcat(@view); } sub today{ #今日のカウンタ============= @countdatadt = split(//, $today); foreach $coudt(@countdatadt){ push(@viewdt, "./img-d/$coudt.gif"); } print "Content-type:image/gif\n\n"; binmode(STDOUT); print &gifcat::gifcat(@viewdt); } sub yestaday{ #今日のカウンタ============= @countdatady = split(//, $yesday); foreach $coudy(@countdatady){ push(@viewdy, "./img-d/$coudy.gif"); } print "Content-type:image/gif\n\n"; binmode(STDOUT); print &gifcat::gifcat(@viewdy); }
- kumoz
- ベストアンサー率64% (120/185)
count.html の中から何度も count.cgi を呼び出して、その都度インクリメントして いるためと思います。クエリ文字列が total のときのみインクリメントするようにす ると直るかもしれません。 if ($day == $mday) { &totalcount() if $ENV{QUERY_STRING} =~ /total/; } else { ... &totalcount() if $ENV{QUERY_STRING} =~ /total/; }
補足
回答ありがとうございました!言われてみれば、そのとおりですよね。何度もcount.cgi を呼び出していたので、カウント数がおかしかったんですね。で、kumoz様がおっしゃったように &totalcount() if $ENV{QUERY_STRING} =~ /total/; を記述したみたのですが、トータルカウント数は正常に動くのですが、本日のカウントがおかしいです。何度もカウントを回すと、突然2つ増えたりしてしまいます。 再度教えて頂きたいのですが、本日のカウントも正常に動くようにするには何処を直せばよいでしょうか?よろしくお願い申し上げます。
補足
理屈は分かったのですが、さらに悪化しました。本日も総カウントも「HTMLの表示の方が突然2つ増えてしまうという現象」が発生してしまいました。・・・もう少し自分で勉強してみようと思います。ここまでおつきあい頂きまして、誠にありがとうございました!とても勉強になりました!!