アクセスカウンタ

シンプルなアクセスカウンタを作ってみよう

アクセスカウンタの仕組みはそれほど難しくありません。まずはカウンタの数値を記録しておく外部ファイルを作成します。そのファイルの1行目、1文字目に「0」と記入しておきます。アクセスカウンタのPHPスクリプトはそのファイルを読みにいき、そこに記述されている数値を読み出しその数値に「1」を足します。その「1」を足した数値を画面に出力するとともに、外部ファイルの数値を1を足した数値で上書きします。この例では「count1.dat」という外部ファイルを作成し、その数値を記録します。PHPから読み書きが可能になるよう「count1.dat」のパーミッションは「666」とします。FFFTPの場合は右クリック→属性変更でパーミッションの設定をしてください。

スクリプト

<?php
	$file = 'count1.dat';
	$fp = fopen($file, 'r+');
	flock($fp, LOCK_EX);
	$count = fgets($fp, 16);
	$count++;
	fseek($fp, 0);
	fputs($fp, $count);
	flock($fp, LOCK_UN);
	fclose($fp);
	$count = sprintf('%06d', $count);
	echo $count;
?>

実行結果

006179

解説

$file = 'count1.dat'
カウンタの数値が記録されているファイル「count1.dat」を変数「$file」に代入しています。
$fp = fopen($file, 'r+')
fopen関数で「$file」を読み書き可能状態(r+)で開き、そのファイルポインタ(カーソルの位置みたいなものでこの場合ファイルの先頭になります)を$fpに代入しています。
flock($fp, LOCK_EX)
ファイルがオープンしている状態でさらにアクセスがあった場合、「count1.dat」ファイルが破損してしまう可能性があるので、ファイルを一旦ロックします。
$count = fgets($fp, 16)
16バイト目までの文字列(この場合文字列が半角なので16文字)を取得し、変数「$count」に代入します。
$count++
変数「$count」に代入されている数値に1をプラスします。
fseek($fp, 0)
ファイル「count1.dat」の数値を読み込むことでファイルの1番最後に移動してしまったファイルポインタを先頭に戻します。
fputs($fp, $count)
最新の数値で「count1.dat」に記録されている値を上書きします。
flock($fp, LOCK_UN)
ファイル「count1.dat」のロックを解除します。
fclose($fp)
ファイル「count1.dat」を閉じます。
$count = sprintf('%06d', $count)
sprintf関数でカウンタに表示される数値の桁数を6桁に指定し、変数「$count」の値が「1」の場合は「000001」と表示されるよう整形しています。最初の引数を「%07d」とすれば7桁になります。
echo $count
変数「$count」に代入されている値を画面に出力しています。

ちょっと工夫したアクセスカウンタを作ってみよう

超シンプルなアクセスカウンタが出来上がりましたが、このままではページを更新するたびにカウンタの値が増えていってしまい、実際にどの程度の人がページを見てくれているのかわかりづらくなってしまいます。そこで今度は訪問者のIPアドレスを記録し、記録されているIPアドレスからのアクセスについては、カウントの値を増やさないという機能を追加します。「count2.dat」には「0,」と記述しておき、カンマの後には最後にアクセスしたIPアドレスが記録されるようにします。ただし、fopen($file, "r+")でファイルを読み書きを行う際、IPアドレスが前回アクセスしてきたもの方が長い場合、上書き時に前回のIPアドレスの長い部分が上書きされずに残ってしまいます。それを回避するために、今回は、fopen($file, "r")で文字列を読み込み後に一旦ファイルを閉じ、書き込み時にはfopen($file, "w")で再度ファイルを開いています。fopenのモードを「w」とすることでファイルサイズをゼロにしたのちにファイルへの書き込みを実行します。

スクリプト

<?php
	$file = 'count2.dat';
	$fp = fopen($file, 'r');
	$line = fgets($fp, 32);
	fclose($fp);
	$array = explode(',', $line);
	$count = $array[0];
	if($array[1] != $_SERVER['REMOTE_ADDR']){
		$count++;
		$new_array = array($count, $_SERVER['REMOTE_ADDR']);
		$new_line = implode(",", $new_array);
		$fp = fopen($file, 'w');
		flock($fp, LOCK_EX);
		fputs($fp, $new_line);
		flock($fp, LOCK_UN);
		fclose($fp);
	}
	$count = sprintf('%06d', $count);
	echo $count;
?>

実行結果

004899

解説

$count = fgets($fp, 32)
今回は記録されたIPアドレスまで記録されているので32バイトまで取得できるようにしています。
$array = explode(",", $line)
「count2.dat」から取得した内容をカンマでカウント値とIPアドレスに分割し、配列「$array」に格納しています。
$count = $array[0]
配列「$array」のカウント値の部分を変数「$count」に代入しています。
if($array[1] != $_SERVER['REMOTE_ADDR']){ … }
配列「$array」のIPアドレスの値とアクセスに来ているIPアドレスを比較して同じでなければ{ }内の処理を実行します。
$new_array = array($count, $_SERVER['REMOTE_ADDR'])
1プラスされたカウント値とアクセスに来ているIPアドレスの値で配列を生成しています。
$new_line = implode(",", $new_array)
配列「$new_array」から「count2.dat」へ上書きするための文字列を生成しています。

画像を使ったアクセスカウンタを作ってみよう

せっかくアクセスカウンタが作れるようになったものの「どうせなら画像でカウンタを表示したい」と思ってしまうのはまったくをもって当然の発想です。というわけで今回はカウンタの値を作ってみたいと思います。「0.gif」から「9.gif」までの10個の画像を用意し、この例ではドキュメントルート直下の「images」ディレクトリに画像をアップロードしておきます。

スクリプト

<?php
	$file = 'count3.dat';
	$fp = fopen($file, 'r');
	$line = fgets($fp, 32);
	fclose($fp);
	$array = explode(',', $line);
	$count = $array[0];
	if($array[1] != $_SERVER['REMOTE_ADDR']){
		$count++;
		$new_array = array($count, $_SERVER['REMOTE_ADDR']);
		$new_line = implode(',', $new_array);
		$fp = fopen($file, 'w');
		flock($fp, LOCK_EX);
		fputs($fp, $new_line);
		flock($fp, LOCK_UN);
		fclose($fp);
	}
	$count = sprintf('%06d', $count);
	for($i = 0; $i < strlen($count); $i++){
		$image = substr($count_str, $i, 1);
		echo '<img src="/images/'.$image.'.gif" alt="'.$image.'" width="30" height="30" />';
	}
?>

実行結果

004899

解説

for($i = 0; $i < strlen($count); $i++){…}
変数「$i」に0を代入し、「$i++」で処理が1回終了するごとに$iの値が1つずつ増えていきます。「strlen($count)」で変数「$count」の文字列の長さ(この例の場合6文字)を取得します。「$i」の値が「strlen($count)」の値より小さい間は処理が続けられますので、$iの値が「0」から「5」の間、計6回{ }内の処理を実行します。
$image = substr($count, $i, 1)
substr関数で取得した文字列を変数「$image」に代入しています。引数は「文字列, 取出し位置, 文字列の数」となるので、初回は文字列000001の先頭から1文字取り出すということになるので「0」が取り出されます。
echo '<img src="/images/'.$image.'.gif" alt="'.$image.'" width="30" height="30" />'
imgタグで変数「$image」.gifの画像ファイルを指定しています。

▲ページトップに戻る