ACCESSアナライザー

 クッキー機能を使って、重複のない正確なアクセスデータを取得する、アクセス解析スクリプトを作って見ました。まあ、基本的にはPerl版スクリプトの内容を参考にさせてもらっていますが…(^^ゞ

 処理内容は、アクセスした日付、ホスト名、ブラウザ名、アクセス時刻をログファイルに保存し、そのデータを元にアクセス内容を分析・表示するものです。データの加工の仕方は、まだ色々と工夫出来そうですが、まずは基本的な所から…(^^ゞでは、そのコード内容をご覧下さい。

注意点

 アクセス解析をするページ本体もPHPスクリプトにしておく必要があります。その中で、include文によってアクセス解析スクリプトを呼び出すようにします。

ページ本体

ana_smp.php

<?php include "ana.php"; ?> PHPスクリプトを呼び出します。
<HTML>
<HEAD>
<TITLE>アナライザー・サンプルページ</TITLE>
</HEAD>
<BODY>
<P ALIGN="CENTER"><FONT SIZE="6" COLOR="#006600">アナライザー・サンプルページ</FONT></P>
<P>
<HR ALIGN="CENTER">
</P>
<CENTER>
<P>ここにお好きな内容を入れて下さい。</P>
<P>解析結果を見たい時は、下のバナーをクリックしてね(^o^)丿</P>
</CENTER>
<P ALIGN="CENTER"><A HREF="ana.php?action=view"><IMG SRC="komo_ana.jpg" ALIGN="BOTTOM"
BORDER="0"></A>
</BODY>
</HTML>
HTML本文です。

PHPスクリプト

ana.php

<?php PHP開始の合図。
//=================初期設定==================
$title = 'KOMOアナライザー';
$date_now = date("Y/m/d(D)"); //日付の取得
$hour = date("H"); //時刻の取得
$graph_img = './cnt.gif';
$data_file = './ana.dat'; //データファイル
$max = 1000; //最大記録数
$hostview = 50;
$agentview = 50;
$graphview = 100;
$date_max = 31;
$time_max = 24;
初期設定です。

大方の設定は、この部分で変更可能です。
//=================データ分析==================
if($action == 'view'){
 $v_data = file($data_file);
 $v_cnt = count($v_data);
 for($i=0; $i<$v_cnt; $i++){
  list($da,$ho,$ag,$hr) = split(",", $v_data[$i]);
  $DA[$da]++; //日付毎の集計
  if($date_now == $da){
   $TI[$hr]++; //時間毎の集計(当日のみ)
  }
  $HO[$ho]++; //ホスト毎の集計
  $AG[$ag]++; //ブラウザ毎の集計
 }
アクセス解析をするページ本体で、解析結果を表示する為のボタンを押すと($action == 'view')、まずここの基本的なデータ分析が行われます。

データの総数をカウントし、それぞれの要素を連想配列に格納して行く事によって、それぞれの総カウント数も取得します。
 //並べ替え
 if($v_cnt > 0){
  while(list($key,$value)= each($DA)){
   $dummy = "$key,$value";
   $DATE[ ] = "$dummy";
  }
  list($d,$datecount) = split(",", $DATE[0]);
最初の条件式は、データが存在しない時のエラー対策です。

連想配列
$DAのキーと値を取得し、それぞれを配列$DATEに格納します。

配列
$DATE[0]の値から、当日のカウント総数$datecountを取得します。
  while(list($key,$value)= each($TI)){
   $dummy = "$key,$value";
   $TIME[ ] = "$dummy";
  }
連想配列$TIのキーと値を取得し、それぞれを配列$TIMEに格納します。
  while(list($key,$value)= each($HO)){
   $s = sprintf("%04d", $value);
   $dummy = "$s,$key,$value";
   $HOST[] = "$dummy";
  }
  rsort($HOST);
連想配列$HOのキーと値を取得し、それぞれを配列$HOSTに格納します。変数$sは、データを降順に並び替える(rsort)為のダミー変数です。
  while(list($key,$value)= each($AG)){
   $s = sprintf("%04d", $value);
   $dummy = "$s,$key,$value";
   $AGENT[] = "$dummy";
  }
  rsort($AGENT);
 }
連想配列$AGのキーと値を取得し、それぞれを配列$AGENTに格納します。変数$sは、データを降順に並び替える(rsort)為のダミー変数です。
 //===================HTML出力==================
 echo "<html><head><title>$title</title></head>\n";
 echo "<body bgcolor=#ffffff text=#000000 link='red' vlink='red'>\n";
 echo "<center>\n";
 echo "<p><font size=5 color='green'><最新 $max アクセスの解析結果></font></p>\n";
 echo "<p>現在のサンプル数 $v_cnt アクセスです。</p>\n";
HTML出力します。最初の部分です。
 //本日の時間別統計
 echo "<table border=1 cellspacing=1 width=90%>\n";
 echo "<caption>本日の時間別統計</caption>\n";
当日の時間別統計を表示します。
 echo "<tr><td bgcolor=#ffccff><font size=2>グラフ</font></td>\n";
 if($time_max > count($TIME)){ $time_max = count($TIME); }
 for($i=0; $i<24; $i++){
  for($j=0; $j<$time_max; $j++){
   list($d,$c) = split(",", $TIME[$j]);
   if($c > 0 && $i == $d){
    $chrlen = $c / $datecount * $graphview;
    break;
   } else {
    $chrlen = 0;
   }
  }
  echo "<td align=center valign=bottom><img src=$graph_img width=10 height=$chrlen></td>\n";
 }
 echo "</tr>\n";
グラフ図形を表示します。時間表示は24時間全てにしていますので、ループ処理を二重にして、該当するデータだけを取り出しています。条件式「$i == $d」は、セルを表す変数$iが時間を表す変数$dと等しければ、と言う意味です。条件が合致すれば、break文によって内部ループを抜けます。
echo "<tr><td bgcolor=#ffccff><font size=2>時間</font></td>\n";
 for($i=0; $i<24; $i++){
  echo "<td>$i</td>\n";
 }
 echo "</tr>\n";
時間の表示部分は簡単です。変数$iをそのまま順に表示します。
 echo "<tr><td bgcolor=#ffccff><font size=2>カウント</font></td>\n";
 if($time_max > count($TIME)){ $time_max = count($TIME); }
 for($i=0; $i<24; $i++){
  for($j=0; $j<$time_max; $j++){
   list($d,$c) = split(",", $TIME[$j]);
   if($c > 0 && $i == $d){
    $c2 = $c;
    break;
   } else {
    $c2 = 0;
   }
  }
  echo "<td>$c2</td>\n";
 }
 echo "</tr>\n";
カウント数を表示します。ここの処理は、グラフ表示部分とほほ同じです。条件に合致したデータを取得し、そのまま表示します。
 echo "<tr><td bgcolor=#ffccff><font size=2>ポイント(%)</font></td>\n";
 for($i=0; $i<24; $i++){
  for($j=0; $j<$time_max; $j++){
   list($d,$c) = split(",", $TIME[$j]);
   if($c > 0 && $i == $d){
    $per = $c / $datecount * 100;
    break;
   } else {
    $per = 0;
   }
  }
  echo "<td>\n";
  printf("%d", $per);
  echo "</td>\n";
 }
 echo "</tr></table><br>\n";
ポイント数を表示します。ここの処理も上と同様です。
 //日別統計
 echo "<table border=1 cellspacing=1 width=90%>\n";
 echo "<caption>日別統計(最大 $date_max 日)</caption>\n";
 echo "<tr><td align=center bgcolor=#ffccff><font size=2>日付</font></td>\n";
 echo "<td align=center bgcolor=#ffccff><font size=2>カウント</font></td>\n";
 echo "<td align=center bgcolor=#ffccff><font size=2>ポイント</font></td>\n";
 echo "<td align=center bgcolor=#ffccff><font size=2>グラフ</font></td></tr>\n";
 if($date_max > count($DATE)){ $date_max = count($DATE); }
 for($i=0; $i<$date_max; $i++){
  list($d,$c) = split(",", $DATE[$i]);
  if($v_cnt == 0){
   $per = 0;
   $chrlen = 0;
  } else {
   $per = $c / $v_cnt * 100;
   $chrlen = $c / $v_cnt * $graphview;
  }
  echo "<tr><td>$d</td>\n";
  echo "<td align=right>$c</td>\n";
  echo "<td align=right>\n";
  printf("%10.2f", $per);
  echo " %</td>\n";
  echo "<td><img src=$graph_img width=$chrlen height=10></td></tr>\n";
 }
 echo "</table><br>\n";
日別統計を表示します。

処理の内容については、上記のものとほぼ同じです。
 //ホスト別統計
 echo "<table border=1 cellspacing=1 width=90%>\n";
 echo "<caption>ホスト別統計(最大 $hostview 件)</caption>\n";
 echo "<tr><td align=center bgcolor=#ffccff><font size=2>ホスト名</font></td>\n";
 echo "<td align=center bgcolor=#ffccff><font size=2>カウント</font></td>\n";
 echo "<td align=center bgcolor=#ffccff><font size=2>ポイント</font></td>\n";
 echo "<td align=center bgcolor=#ffccff><font size=2>グラフ</font></td></tr>\n";
 if($hostview > count($HOST)){ $hostview = count($HOST); }
 for($i=0; $i<$hostview; $i++){
  list($s,$h,$c) = split(",", $HOST[$i]);
  if($c != 0){
   if($v_cnt == 0){
    $per = 0; $chrlen = 0;
   } else {
    $per = $c / $v_cnt * 100;
    $chrlen = $c / $v_cnt * $graphview;
   }
  }
  echo "<tr><td>$h</td>\n";
  echo "<td align=right>$c</td>\n";
  echo "<td align=right>\n";
  printf("%10.2f", $per);
  echo " %</td>\n";
  echo "<td><img src=$graph_img width=$chrlen height=10></td></tr>\n";
 }
 echo "</table><br>\n";
ホスト別統計を表示します。

処理の内容については、上記のものとほぼ同じです。
 //ブラウザ別統計
 echo "<table border=1 cellspacing=1 width=90%>\n";
 echo "<caption>ブラウザ別統計(最大 $agentview 件)</caption>\n";
 echo "<tr><td align=center bgcolor=#ffccff><font size=2>ブラウザ名</font></td>\n";
 echo "<td align=center bgcolor=#ffccff><font size=2>カウント</font></td>\n";
 echo "<td align=center bgcolor=#ffccff><font size=2>ポイント</font></td>\n";
 echo "<td align=center bgcolor=#ffccff><font size=2>グラフ</font></td></tr>\n";
 if($agentview > count($AGENT)){ $agentview = count($AGENT); }
 for($i=0; $i<$agentview; $i++){
  list($s,$a,$c) = split(",", $AGENT[$i]);
  if($c != 0){
   if($v_cnt == 0){
    $per = 0; $chrlen = 0;
   } else {
    $per = $c / $v_cnt * 100;
    $chrlen = $c / $v_cnt * $graphview;
   }
  }
  echo "<tr><td>$a</td>\n";
  echo "<td align=right>$c</td>\n";
  echo "<td align=right>\n";
  printf("%10.2f", $per);
  echo " %</td>\n";
  echo "<td><img src=$graph_img width=$chrlen height=10></td></tr>\n";
 }
 echo "</table>\n";
 echo "</center></body></html>\n";
ブラウザ別統計を表示します。

処理の内容については、上記のものとほぼ同じです。
 unset($v_data); 指定した変数の割り当てを解除します。
} else {
 //クッキー書き込み
 $cookie = $date_now;
 setcookie("Cookie","$cookie");
重複のない正確なデータを採る為に、クッキーに接続時の日付情報を書き込みます。
 //データ書き込み
 if($Cookie != $date_now){
クッキーから得た日付情報と、接続時の日付情報とが異なっていれば、データファイルに書き込みをします。
  //ホスト名を取得
  $host = getenv("REMOTE_HOST");
  $addr = getenv("REMOTE_ADDR");
  if($host == "" || $host ==$addr){
   $host = gethostbyaddr($addr);
  }
  //訪問者のブラウザを取得
  $agent = getenv("HTTP_USER_AGENT");
  $ana_data = file($data_file);
  $value = "$date_now,$host,$agent,$hour\n";
  $fp = fopen($data_file, "w");
  rewind($fp);
  fputs($fp, $value);
  //最大記録数の調整
  if($max <= count($ana_data))
   $ana_num = $max - 1;
  else
   $ana_num = count($ana_data);
  for($i = 0; $i < $ana_num; $i++){
   fputs($fp, $ana_data[$i]);
  }
  fclose($fp);
  unset($ana_data);
 }
}
この部分の処理内容は、掲示板スクリプトなどで見られるものと一緒です。
?> PHP終了の合図。

 *上の内容をこのまま複写しても動きません。何故なら、表示を見やすくする為コード中に全角スペースが入っているからです。実際にお使いになる時は、この点を修正してからサーバにアップして下さい。

HOME