• 締切済み

二重カウント防止

フリーのカウンタに2重カウントを防止出来るようにいろんなHP見て直したのですが、カウンタ自体動作しなくなりました。どこを直せばよいのでしょうか // 連続カウント防止(yes=1 no=0) $ip_check = 1; //------------ここまで---------- $fp = @fopen($log, "r+") or die($log."が開けません"); $count = fgets($fp, 64); //最大64バイトまで読み込む if(($ip_check == 1 && "$ip" != $_SERVER["REMOTE_ADDR"]) || $ip_check == 0){ $cnt++; $new_data = implode("<>", array($cnt,$_SERVER["REMOTE_ADDR"])); } fseek($fp, 0); //ファイルポインタを先頭に移す flock($fp, 2); //書き込みに対しロック fputs($fp, $count); //ファイルに書き込む fclose($fp); //ファイルをクローズ //桁数のフォーマット $cnt = sprintf(sprintf("%%0%dd", $fig), $count); //画像のサイズオプションを0.gifで取得 $size = getimagesize($path."0.gif"); //IMGタグを出力 for ($i=0; $i<strlen($cnt); $i++): //桁数分だけループ $n = substr($cnt, $i, 1); //左から一桁ずつ取得 echo "<IMG SRC=\"$path$n.gif\" alt=$n $size[3]>"; endfor;?>

  • PHP
  • 回答数5
  • ありがとう数2

みんなの回答

  • sisya
  • ベストアンサー率39% (97/245)
回答No.5

#2の補足への返事になってしまいますが、 「素人でも既存のスクリプトの拡張ならさほど難しくはないです」 m-happy-tさんのような 「自分の欲しい機能をなんとか実装したい」と言う気持ちがあれば、 ゆっくりでも確実に理解していけると思います。 ただ、今回のような答え様の無い質問の仕方ですと、 有効回答を得られず、放置される場合が多いので こちらの事も少し考えて頂きたいのです。 ご本人なら当然判っているような事も こちらは全然判らない状態で答えていると言う事です。 「質問するなら最低限の情報は書いてください」 これは技術的質問に限らず、人に何かを尋ねる上での基本だと思います。

m-happy-t
質問者

お礼

本を買ってきました。 呼んで考えます

  • sisya
  • ベストアンサー率39% (97/245)
回答No.4

全部推測ですが、 とりあえず ・「$ip」と言う変数に値を代入していない ・「$new_data」を保存していない この2点は問題ですね この元となったスクリプトは 「$_SERVER["REMOTE_ADDR"]をファイルに保存しておき、  既に保存済のipだった場合はカウントをしない」 と言う処理を行っています。 よって下記スクリプトには以下の2点が足りません。 ・カウント済ip一覧を読み込み、すでに記録されているかのチェック ・カウントしたipを保存する処理

  • sisya
  • ベストアンサー率39% (97/245)
回答No.3

確かに手段として「追加して動かなくなった」のは理解できました。 ここで質問の仕方を説いても仕方ないのですが、 最低でも以下の情報がなければ答えようがありません。 ・そもそもどこから持ってきた何を追加したのか (1行1行比較すればわかる事なのかもしれませんが) ・どんなエラーが表示されたのか ・動作させている環境 また、以下の情報があると質問した方の理解度が判り、 より教えやすくなると思います。 ・PHPで以前何かを作った経験はあるのか ・そもそも言語を扱ったことがあるのか 質問をする時はまず他の質問を見て どうやって質問しているのかを見てみましょう。 それによって回答とのやり取りから どうやって自力で問題を解決するかが身につきます。 なぜ私が「丸投げ」などという厳しい書き方をしたかを もう少し考えて欲しかったです。

m-happy-t
質問者

補足

・そもそもどこから持ってきた何を追加したのか 元はここの画像カウンターです http://php.s3.to/counter/ 追加した分は、忘れました ・どんなエラーが表示されたのか エラーはありませんが、カウントしません(当たり前ですよね) ・動作させている環境 PHPのバージョンは、4.2.3です ・PHPで以前何かを作った経験はあるのか ありません ・そもそも言語を扱ったことがあるのか ありません 素人には無理であれば、無理と言っていただいて結構です

  • sisya
  • ベストアンサー率39% (97/245)
回答No.2

そもそもどういう手段を講じて2重カウントを防止しようとして、動かなくなったのでしょうか? (全く補足なしでデバッグの丸投げはちょっと乱暴すぎるのではないかと)

m-happy-t
質問者

補足

私の利用しているHPスペースはこの画像カウンタ以外は利用できません。本カウンタは重複カウント防止になっていないため、他のカウンタの重複カウント防止と思われるところを以下のカウンタに追加したら動かなくなりました (そんな、ことで動くと思ったら大間違いと指摘されると思ってます) お付き合い頂けるのであれば、よろしくお願いします 設置した無料カウンタの構文は以下のとおりです。 <? //------------設定--------------- // カウンタ画像のあるディレクトリ $path = './gif/'; // カウンタを記録するファイル $log = 'count.txt'; // カウンタの桁数 $fig = 5; //------------ここまで---------- $fp = @fopen($log, "r+") or die($log."が開けません"); $count = fgets($fp, 64); //最大64バイトまで読み込む $count++; //カウントアップ fseek($fp, 0); //ファイルポインタを先頭に移す flock($fp, LOCK_EX); //書き込みに対しロック fputs($fp, $count); //ファイルに書き込む fclose($fp); //ファイルをクローズ //桁数のフォーマット $cnt = sprintf("%0".$fig."d", $count); //画像のサイズオプションを0.gifで取得 $size = getimagesize($path."0.gif"); //IMGタグを出力 for ($i=0; $i<strlen($cnt); $i++){ //桁数分だけループ $n = substr($cnt, $i, 1); //左から一桁ずつ取得 echo "<IMG SRC=\"$path$n.gif\" alt=$n $size[3]>"; }?>

  • Dpop
  • ベストアンサー率51% (279/544)
回答No.1

他の方が回答してくださるかも知れないので、 直接的な答えではなく、「理屈」についてお話しします。 多重カウントを防止する。と言うことはどう言うことでしょうか? 答えはとても簡単でして、多重起動してしまうから、多重カウントしてしまうのですよね。 と、言うことは、多重起動しない様なプログラムを作ればよ良いのです。この様な仕組みのことを「ロック」とか「ファイルロック」とかと言います。この言葉を Google などで検索して頂くと、幾つかの方法論が紹介されたページを見つけることができるでしょう。 対応言語は、Perl である可能性は高いですが、論理は同じです。(PHP が分かる方なら、Perlもなんとなくは分かると思います。(逆も同じ。)) 例えば、処理が始まる時に、ある決まったファイルをオープンし、処理が終了したら削除する仕組みを用意します。 ファイルをオープンする前に、そのファイルが存在しているのか、チェックをします。もし、見つかれば他のプロセスで起動中であることが分かるし、もし存在しなければ多重起動しない可能性が濃厚です。(絶対に多重起動しない。と言う保障はありません。タイミング的に同一タイミングになるケースがありますよね。) もし、ファイルが存在していれば、一定時間待った上で再度ファイルをチェックします。それを複数回実行して、存在していたら、タイムアウトとする。 などとすれば良さそうですよね。(これが、アルゴリズムの全体です。) ファイルをオープンするのではなく、ディレクトリを作るとか。あるファイルの内容を変更する。などと言う方法でも、起動中かどうか、見極めることができそうですよね? もちろん、flook を使っても良いですね。(僕は、使いませんけど。(笑)) これをヒントにプログラムを見直してみましょう。間違えが見つかりますよ。

関連するQ&A

  • カウンターで重複カウントの防止について

    勉強がてら以下のようなカウンターをつくりたいと思っています。 1 画像つきのカウンタである 2 重複カウンタを防止したい 3 昨日と今日のカウンターも表示させたい で、2でけつまずきました。 何がいけないのでしょうか? 以下のプログラムだと更新毎にカウンターが回ってしまいます。 ご指摘下さい。よろしくお願い申し上げます。 #!C:\Perl\bin\perl $flg = 0; #IPアドレスの取得と重複カウントの防止============ $ipadd = $ENV{'REMOTE_ADDR'}; #IPアドレスの取得 open (FILE, "<logcount.dat") || die "File Open Err!-logcount.dat\n"; #データをすべて配列logdataに読み込む @logdata = <FILE>; close(FILE); #取得したIPアドレスと履歴のIPアドレスを比較====== for($i=0; $i<=$#logdata; $i++){ if($ipadd eq $logdata[$i]){ #新規のIPデータと過去ログのIPデータが等しかったら $flg = 1; #合致するのは1つのアドレスのみ } } #==================================================================== # $flg = 0 だったら、数をカウント #==================================================================== open(FILE,"<count.dat") || die "File Open Error!-count.dat\n"; #カウントデータの読み込み $count = <FILE>; #変数countにデータを収納 close(FILE); if($flg == 1){ $data = $count; }else{ $data = ++$count; #プラス1をカウント # ログの更新================================== open(FILE, "+<count.dat") || die "File Open Error!\n"; flock(FILE,2); seek(FILE, 0, 0); #.datに上書き保存する為にデータの記位置を調整 print FILE $data; #カウントを記録 flock(FILE,8); close(FILE); # IPアドレスを更新============================= open (FILE, ">>logcount.dat") || die "File Open Err!-logcount.dat\n"; print FILE $ipadd,"\n"; close(FILE); } print $data; #==================================================================== # カウンタの数字に画像を付ける #==================================================================== @count = split(//, $data); foreach $cou(@count){ push(@view, "./img/$cou.gif"); } require "./gifcat.pl"; print "Content-type:image/gif\n\n"; binmode(STDOUT); print &gifcat::gifcat(@view);

    • ベストアンサー
    • Perl
  • PHPで作ったカウンタを任意の位置における

    ようにしたいのですができません counter.php: <?php $data_file = './access.dat'; //データファイル $fp = fopen("$data_file", "r+"); $cnt_num=(string)(fgets($fp, 64)+1); fseek($fp,0); flock($fp,2); fwrite($fp,$cnt_num); fclose($fp); $cnt_num=sprintf("%06d",$cnt_num); $f_pass = './a_gif'; for($i=0;$i<strlen($cnt_num);$i++)$value[]=substr($cnt_num,$i,1); for($j=0;$j<count($value);$j++)echo "<img src=$f_pass/".$value[$j].".gif>"; ?> としてHTMLの任意位置で <img src="./counter.php"/> をおいたのですが×マークが出るだけでカウンタ値が表示されません どうしたらいいでしょうか

    • ベストアンサー
    • CGI
  • ページ表示ごとにカウントダウンをさせたい。

    こんばんわ。 こんなスクリプトを組んでみました。 phpは勉強を始めたばかりです。 <? echo "Hello world!!";?> <br> あなたのIPは <? echo $_SERVER["REMOTE_ADDR"]?> ですね? <br> ただいま<? print (date ("Y年m月d日(D) H時i分s秒"));?>です <br><br> <?php $fp = fopen ("count.txt","r+"); $count = fgets ($fp, 32); $count--; fseek($fp, 0); fputs($fp, $count); flock($fp,2); $count = sprintf("%05d", $count); fclose($fp); echo $count ?> ログファイルは初期値として、10としました。 が9までは正常に減っていくのですが、次に8にならずに 89になってしまいます。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • PHP チャットの相手の入場時にチャイム鳴動

    下記のPHPスクリプトで、自分が先にチャットのページを開いていたとして、 相手がチャットのページを開いたら(入場したら)チャイムを鳴動させたいのですが、 相手が入場したときに、相手側にしか音が鳴りません。こちらは、相手がいつ入場したのか わかるために、チャイムを鳴動させたいのですが、どこがどう間違っているのでしょうか。 ご指導よろしくお願い致します --------------------------------------------------------------------------------------------------- /////////////////////////////////////////////////// // IPアドレスをファイルに保存 // /////////////////////////////////////////////////// function reserveIpAdress(){ $filename="ip_log.txt"; if(!filesize($filename)){ // ファイルが空だったら $fp = fopen($filename, 'w'); // 追加書き込み用に、IPログファイルをオープン $buf = $_SERVER['REMOTE_ADDR']."\n"; fwrite($fp, $buf); // IPアドレスを追加書き込み fclose($fp); echo '<audio src="http://5247423.raindrop.jp/chat/music/schjoin.hso" autoplay></audio>'; $_SESSION['ip_write_cnt']++; }else{ $fp = fopen($filename, 'r'); // while(($buf=fgets($fp))===false){ $buf = fgets($fp); // 1行目 // $buf1 = rtrim($buf1); // $buf2 = fgets($fp); // 2行目 fclose($fp); if(rtrim($buf)!==$_SERVER['REMOTE_ADDR']){ // 相手の方が先にチャットにアクセスした時 $fp = fopen($filename, 'a'); $buf2 = $_SERVER['REMOTE_ADDR']."\n"; // 自分のIPアドレスをファイルにライト fwrite($fp, $buf2); fclose($fp); echo '<audio src="http://5247423.raindrop.jp/chat/music/schjoin.hso" autoplay></audio>' }else{ } $_SESSION['ip_write_cnt']++; } } /////////////////////////////// // メインルーチン // /////////////////////////////// session_start(); // セッション開始 if(is_null($_SESSION['ip_write_cnt'])) $_SESSION['ip_write_cnt'] = 0; if($_SESSION['ip_write_cnt']<2){ // 2人でチャットする場合 reserveIpAdress(); // このページにアクセスしたデバイスのIPアドレスをファイルにライト } 以下略

    • ベストアンサー
    • PHP
  • PHPにてアクセスカウンターを作成してるのですが

    PHPを勉強しているのですが、以下のプログラムで画像アクセスカウンターを作成してるのですが、 <?php $date_now = date("Y/m/d"); $cookie = $date_now; setcookie("Cookie",$cookie); ?> <html><head></head><body> <?php $data_file = './access.dat'; $fp = fopen("$data_file", "r+"); $cnt_num = fgets($fp, 64); if($Cookie != $date_now){ $cnt_num++; fseek($fp, 0); flock($fp,2); fwrite($fp, $cnt_num); } fclose($fp); $f_pass = './a_gif'; for($i = 0; $i < strlen($cnt_num); $i++) $value[ ] = substr($cnt_num, $i , 1); for($j = 0; $j < count($value); $j++) echo "<img src=$f_pass/" . $value[$j] . ".gif>"; ?> </body> </html> うまく表示できません。 access.datに何か記述するのでしょうか? a_gifファイルに画像も入れてるのですがパーミッションなどを変更するのでしょうか? 作業環境はWindowsXPを使用してます。 サーバーはロリポップにて借りてます。 一応access.datのパーミッションは666に設定してます。

    • 締切済み
    • PHP
  • 【続】VBSでメール件数カウント(サブフォルダ有)

    「VBSでメール件数カウント」の続きなのですが、 「受信フォルダ」の下にサブフォルダがあった場合の、 件数カウントはどうすればよいでしょうか? 試しに作ってみましたのですが、自信がないので、 よろしければ診ていただけないでしょうか? ------------------------------------------------------------ Private Function Cnt_MailItem Cnt_MailItem = 0 Set oApp = CreateObject("Outlook.Application") Set oNs = oApp.GetNameSpace("MAPI") Set oFol = oNs.GetDefaultFolder(6) '受信アイテイム Cnt_MailItem = oFol.Items.Count 'サブフォルダカウント Cnt_MailItem = Cnt_MailItem + Cnt_SubFol(oFol) msgbox "メール数:" & Cnt_MailItem End Function 'サブカウント Private Function Cnt_SubFol(byVal pFol ) 'サブがない場合は数えない If pFol.Folders.Count <= 0 Then Exit Function End If For i = 1 To pFol.Folders.Count Set oItems = pFol.Folders.Item(i) Cnt_SubFol = Cnt_SubFol + oItems.Items.Count + Cnt_SubFol(oItems) next Set oItems = Nothing End Function ------------------------------------------------------------ よろしくお願い致します。

  • C言語の質問です。

    前にも質問したのですがなかなかうまくいかないのでよろしくお願いします。 データの書いてあるファイルを読み込んで処理するプログラムを書きたいと考えています。 読み込むデータ 0.012500 0.499167 1.382500 1.534444 2.489167 3.635000 3.775000 5.407500 5.705000 5.916667 6.115833 6.295278 6.825278 7.079722 . . . . この様な数値のかいてあるデータを使って0.5ずつに区切ってその中に何個データがあるか数えたいと考えています。(データは1万5千個以上あります) 例えば上のデータで考えると 0~0.5の範囲のデータは2個 0.5~1の範囲のデータは0個 1~1.5の範囲のデータは1個 1.5~2の範囲のデータは1個 2~2.5の範囲のデータは0個。。。 という風に数えるプログラムにしたいです。 僕が分からないところはどのように場合分けしていくか。。。です。 #include<stdio.h> //#include<process.h> int main(void) { FILE *fp; double n; int cnt,i,Cnt; fp=fopen("1.dat","r"); if(fp==NULL) { printf("file open error!!\n"); exit(1); } i=0; cnt=0; Cnt=0; while(fscanf(fp,"%lf\n",&n)!=EOF){ if(i<=n<(i+0.5)){ cnt++; printf("%lf %d\n",i,cnt); } else if((i+0.5)<=n<(i+1)){ Cnt++; printf("%lf %d\n",i,Cnt); } else{ i++; } } fclose(fp); return 0; } 僕の考えはデータを読み込む 変数 i を使って if文で i <= n <i+0.5の範囲のときはcntを足していく     i+0.5<= n <i+1の範囲のときはCntを足していく それ以外のときは i を+1して同じことを繰り返す というようなやり方を考えました。 しかしうまくいきませんでした。 どのようにすればよいでしょうか。 よろしくお願いします。

  • 画像を使ったアクセスカウンターですが。。。

    どなたか教えていただければ大変ありがたいです。 画像(0.gif~9.gif)を使用し、アクセスカウンターを作る 次のソースの内、 ------------------------------------------------------------------- #!c:/perl/bin/perl require './sub_lock.pl'; $countfile = "./count.log"; $lockdir = "./lockdir"; exit unless(&lock($lockdir)); open(COUNTFILE, "+<$countfile"); chomp($count=<COUNTFILE>); $count++; seek(COUNTFILE, 0, 0); print COUNTFILE "$count\n"; truncate(COUNTFILE, tell(COUNTFILE)); close(COUNTFILE); &unlock($lockdir); $count_img = sprintf("%04d", $count); $count_img =~ s/(.)/<img src=".\/images\/$1.gif">/g; print "content-type:text/html\n\n"; print $count_img; exit; ------------------------------------------------------------------- $count_img =~ s/(.)/<img src=".\/images\/$1.gif">/g; の 「(.)」と「$1」になっているところが、どうも理解できなくて 困っています。 「=~ s」がパターンマッチであることだけは知っています。 CGI辞書などを調べてもやはり意味がわからず、お手上げ状態です。 どうぞよろしくお願いいたします。

    • ベストアンサー
    • CGI
  • csvファイルを構造体に読み込みたい

    C言語初心者です。 csvファイルのデータを1行ずつ構造体に読み込みたいのですが、うまくできません。 #define MAX_SIZE 100 char filename[] = ″test.csv"; struct ALL_DATA{ int cnt; char list[10]; char addr[10]; char cmd[10]; char csize[10]; char input[10]; char icmd[10]; char input2[10]; }; for (int lp = 0; lp < 10; lp++){ FILE *fp; struct ALL_DATA ADATA[MAX_SIZE]; // 構造体配列の宣言 if ((fp = fopen(filename, "r")) == NULL){ printf("%s open error !\n", filename); exit(1); } for (fc = 0; fc < MAX_SIZE; fc++) { if (feof(fp)){ break; } else{ fscanf(fp, "%d,%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],\n", &ADATA[fc].cnt, ADATA[fc].list, ADATA[fc].addr,ADATA[fc].cmd,ADATA[fc].csize,ADATA[fc].input,ADATA[fc].icmd,ADATA[fc].input2); } } fclose(fp); while (i < MAX_SIZE){ printf("ADATA[i].cnt -> %d, ADATA[i].list -> %s, ADATA[i].addr -> %s, ADATA[i].cmd -> %s, ADATA[i].csize -> %s, ADATA[i].input -> %s, ADATA[i].icmd -> %s, ADATA[i].input2 -> %s\n",ADATA[fc].cnt, ADATA[fc].list,ADATA[fc].addr,ADATA[fc].cmd,ADATA[fc].csize,ADATA[fc].input,ADATA[fc].icmd,ADATA[fc].input2); i++; } } 読み込みたいcsvデータは 1 test 0x0012 write 0x001 yes 0xabc yes 2 testa 0x00cd read 0x024 0x1a3 のように、「数字、文字列・・・」と並んでいます。 このデータを取り込んで表示させたところ、 最初の数字は問題ないのですが、ADATA[i].addr から値がおかしくなり、 ADATA[i].addr = 0x0012write ADATA[i].cmd = write ADATA[fc].csize = 0x001yes のように、16進数を文字列として構造体に入れるときに、次の文字(英字)まで一緒に含んでしまう現象が出ております。 ネットで調べて、csvファイルから構造体に取り込む方法はいくつか見たのですが、同じようにしている(と思っている)のにうまくいかないため、質問させていただきました。 原因がわかる方がいらっしゃいましたら、アドバイスをよろしくお願いいたします。

  • C アルファベットのカウント

    #include<stdio.h> #define N 97 #define M 122 int main(void) { char str[ ]="national university"; int i,h,count; char check; for(h=N-1;h<=M;h++){ h++; char check = (char)h; for(i=0;str[i] != '\0';i++){ if(str[i] = check){ count++; } } printf("%c:%d\n",check,count); } } というコードで、アルファベットをそれぞれ何文字使用しているか調べるつもりだったのですが、結果は次のようになってしまいました。解説お願いします。 a:28 c:56 e:84 g:112 i:140 k:168 m:196 o:224 q:252 s:280 u:308 w:336 y:364 {:392

専門家に質問してみよう