カウンタの作成 誤りの指摘やご意見はこちらへ ご意見板
BBS

PHP Top
項目
カウンタの作成 ↑項目に戻る
カウンタは,何人のお客様が自分のサイトに尋ねてきたか,数えるものです.
とりあえず,作ってみましょう.

simplecounter1.phpを,以下の内容で作成してください.

<?php

//simplecounter1.php

$filename = "counter.dat";

$file = fopen($filename, "r");
$count = fread($file, filesize($filename));

fclose($file);

$count = $count + 1;
print "$count";

$file = fopen($filename, "w");
fwrite($file, $count);
fclose($file);

?>

少しずつコードが長くなってきましたね.
でも,まだまだ大丈夫ですよね?
さあ,さっそく動かす前に,少し下準備が必要です.
このプログラムはcount.datというファイルにカウントした数を格納しています.
count.datファイルをまず作ってあげましょう.

# echo 0 > count.dat
# chmod 606 count.dat

上のコマンドを,simplecounter1.phpと同じフォルダで打ち込んでください.
または,"0"とだけ書いたcount.datというファイルをエディタで作成し,606のパーミッションで
サーバにftpなどで転送してあげても構いません.

さあ,ブラウザから確認してみましょう.



上のように表示されたでしょうか?
「なんだ,あんなにプログラム長いのに,0って表示されてるだけじゃん」
そう思いましたか?甘い!甘いです!ブラウザを再読み込み(リロード)させてください.
どんどん数が増えていくでしょう?そう,お客様の来訪数だけ増えていくのです!!

解説---
プログラムの大きな流れとしては
ファイルから数字を読み込む
数字に1を加える
表示する
ファイルに書き込む

といった感じです.
それでは,個別に見ていきましょう.

$filename = "count.dat";

これは、$filenameという変数に、count.datという文字列を代入しています.

$file = fopen($filename,"r");

fopen関数は、ファイルをオープンする関数です。
ファイルより読み書きする準備をする、と考えてください。
ここでは、$filename(=count.dat)というファイルを、
"r" ,つまり読み込みモード(read)でオープンし、
$fileに ファイルポインタを代入しています。
これ以降、この「ファイルポインタ」というものを使って、ファイルを扱います。

$count = fread($file, filesize($filename));

fread関数は、ファイルよりデータを読み込む関数です。
ここでは、$fileの指すファイルより、$filename(=count.dat)のファイルサイズの大きさだけ、
読み込み、その内容を$countに代入しています。
つまり、count.datの全内容を読み込み、$countに代入しています。

fclose($file);

fcloseは、ファイルをクローズする関数です。
いったん空けたものは閉めておかないとお行儀が悪いですね。
実際、きちんとクローズしておかないとファイルが破壊される可能性が出てきます。

$count = $count + 1;
print "count = $count";

ここで、count.datより読み込まれた数字に1を加え、表示しています。

$file = fopen($filename,"w");
fwrite($file, $count);
fclose($file);

さらに今度はcount.datを"w" 書き込みモードでオープンし、
さきほど1加算された数字を書き込み、クローズしています。
これ以降の内容は「とりあえずカウンタができればいいや」
という人は読み飛ばして結構です。先にお進みください。

ファイルのロック ↑項目に戻る
ファイルをロックし、誤作動(ファイル破壊、データ消失)を防ぎます。
simplecounter2.phpを、以下の内容で作成してください。
count.datは先ほどと共通のものを使いましょう。

<?php

//simplecounter2.php

$filename = "counter.dat";

$file = fopen($filename, "r+"); //
flock($file, 2); //
$count = fread($file, filesize($filename));

//fclose($file);

$count = $count + 1;
print "count = $count";

rewind($file);

//$file = fopen($filename,"w");

fwrite($file, $count);
flock($file, 3); //
fclose($file); //

?>

赤い文字で書かれた部分がsimplecounter1.phpと違う部分です。
(削除されている行(コメントアウトしてある行.灰色になっています.)もあるので 赤い部分だけ変更しても動きません。ご注意!)

さあ、ブラウザから確認してみましょう。
「なんだ、一個目と変わってないじゃん」と思ったあなた!
するどいです!実は見かけ上は何も変わっていません。
ところが、今回は「ファイルのロック」というものを行い、一個目よりも
信頼性を向上させているのです。では、変更点を見ていきましょう。

解説---
$file = fopen($filename,"r+"); //

実は先ほどは黙っていたのですが、ファイルのオープンは「読み込み」「書き込み」モードだけではありません。
"r+"これは、読み書き両方できてしまうという便利なモードです。 今回は、このモードを使いましょう。
一個目は、
「読み込みモードでオープン、読み込み、クローズ」
「書き込みモードでオープン、書き込み、クローズ」
としていましたが、今回はそれが一度で済みます。
fopen関数の引数はr,w,r+だけではありません.調べることをお勧めします. (fopen関数)

flock($file, 2); //

flockは、ファイルロック操作関数です。
2番目の引数である"2"は、「排他的ロック」を表します。(flock関数)
これにより、他プロセスよりファイルにアクセスできなくします。

flock($file, 3); //

"3"は、「ロック開放」を表します。
先ほど行ったロックを解除し、他プロセスよりファイルにアクセスできるように戻します。

rewind($file); //

rewindはファイルポインタを先頭に戻します。
今回は同一ファイルから読み込んだあとに書き込みを行うわけですが、
この場合、ファイルポインタを先頭に戻しておかないと、読み込み終わった部分の次から
書き込みを行ってしまいます。注意してください。
さあ、地味な変更でしたが、いかがでしたか?
プログラムというのは地味で地道なものなんです。
IPの記録 ↑項目に戻る
最後に訪れた人のIPを記録し、より正確な来訪数をカウントします。(リロードしても増えません)
前回までのプログラムは、同じ人がリロードしてしまうとどんどんカウンタが増えていってしまいましたが、今回は、最後に訪問した人の記録を残し、 同じ人が連続で訪問しても、カウンタが増えないようにしています。
それでは、 simplecounter3.phpを、以下の内容で作成してください。

<php?

  $filename = "count_IP.dat";
  $file = fopen($filename,"r+");
  flock($file, 2);

  $count = fgets($file,256);
  $lastIP = fgets($file,256); $IP = getenv("REMOTE_ADDR");

  $count = chop($count);

  if($lastIP != $IP)
$count = $count + 1;

  print("$count");

  //print("lastIP=$lastIP");
  //print("IP=$IP");


  ftruncate($file,0);

  rewind($file);

  fwrite($file, $count);
  fwrite($file, "\n");
  fwrite($file, $IP);

  flock($file, 3);
  fclose($file);

?>

大分プログラムが赤くなってきましたね。
まず、下準備をします。
count_IP.datを以下の内容で作成してください。

0
localhost

パーミッションは606です。
以上で準備OKです。
早速実行してみてください。
リロードしてもカウンタが増えないでしょう!
他のお客様が来た時はきちんと増えるので安心してください。
(可能なら、他のマシンよりアクセスしてみてください。)

解説---

このプログラムを試す

$count = fgets($file,256);
$lastIP = fgets($file,256);

今回は訪問回数と、最終訪問者のIPアドレスと、二つのデータを使用します。

$IP = getenv("REMOTE_ADDR");

環境変数より、閲覧者のIPアドレスを取得します。

$count = chop($count)

chop関数により、文字列末尾の改行記号を取り除いています。

if($lastIP != $IP)$count = $count + 1;

if構文がでてきました。
これはプログラミングに親しんでいる人にはおなじみのものですね。

if (条件) 条件が成立する場合の文;
else 条件が成立しない場合の文;

( )内の条件が成立する場合には、( )以降を実行し、そうでない場合にはelse文以降を実行します。
else文は省略できます。
今回の場合、ファイルに記録されている「最終訪問者のIPアドレス」と、「閲覧者のIPアドレス」
が異なっている場合には$countに1を加え、そうでない場合はなにもしません。

//print("<b>lastIP=$lastIP");
//print("<BR>IP=$IP");

// この記号は、「コメント」を意味します。
//以降の文は、プログラムとしてPHPに解釈されません。つまり、なにを書いてもOKです。
プログラムの説明を埋め込んだり、テスト用のコードを埋め込む場合に使用します。
ここで、二つの//を削除し、実行してみてください。
lastIP と IP の二つの変数の内容が出力されます。

ftruncate($file,0);

ftruncate関数(PHP4以降)を使って、ファイルサイズを切り詰めています。
これをしないと、前回よりも短い容量のデータをファイルに書き込んだ場合、
前回の末尾の部分が残ってしまいます。ご注意!

fwrite($file, $count);
fwrite($file, "\n");
fwrite($file, $IP);

IPアドレスと、訪問回数をファイルに書き込んでいます。
"\n"は、改行記号です。読み込み時にfgets関数を使っているので、
この改行記号が必要です。fgets関数は、改行記号を区切りに使用するからです。

さて、いかがでしたか?
「なんか、結構大変だなあ」という感想でしょうか?
実際、ファイルを扱う場合、細かいことを色々と考えないとうまく動きません。
(データの区切り、末尾データ、ファイルのロック、などなど)

初級者コース以降では、DB(データベース)を使用したプログラミングを行います。
DBを使う場合、上のようなわずらわしいことはありません。
さらに、強力な機能がプログラミングの手間を省いてくれます。
一日わずか10分であなたもDBマスターに!
それに、とっても楽しいんです! レッツ・トライ!!

↑項目に戻る

PHP Top