目次

2011年4月11日

続・アクセスカウンター

数日様子見ていい感じに動いているかな?
予想通りの数字の少なさで泣けてくるけど。

クローラー

デバッグでログ取って気になったのがYahooとgoogleのクローラーの扱い。
BOTなんだからアクセス数から弾くべきなんだろうな~
HTTP_USER_AGENT見ればわかるからとりあえずYahoo! SlurpGooglebotはノーカウントに。

phpコードとか

元ネタはhttp://www.php-z.net/c5/

/lib/counter/
にcount.dat、lock.dat、counter.phpを配置。
/lib/images/counter/
に0.gif~9.gif、today.gif、yesterday.gifを配置。
/lib/tpl/arctic/footer.html
に呼出しコード追加。

/lib/images/counter/0-9.gif


これをバラしたもの。

/lib/counter/counter.php

クローラーとadminログインでノーカウント。
IPを$ipcheck_max個分保持してその間は重複カウント無し。

/lib/counter/counter.php
<?php
function site_counter() {
	global $INFO;
 
	//  同一IPはカウントしない(yes=1 no=0)
	$ipcheck = 1;
	//  重複カウントしないIP保存個数
	$ipcheck_max = 5;
	//  カウント用GIF画像ディレクトリ
	$total_counter_path = DOKU_BASE.'lib/images/counter/';
	$today_counter_path = DOKU_BASE.'lib/images/counter/';
	$yes_counter_path =   DOKU_BASE.'lib/images/counter/';
	$today_img_path = DOKU_BASE.'lib/images/counter/today.gif';
	$yes_img_path =   DOKU_BASE.'lib/images/counter/yesterday.gif';
 
	//  カウンタ記録ファイル
	$count_file = dirname(__FILE__).'/count.dat';
	$lock_file = dirname(__FILE__).'/lock.dat';
	//  カウント数の桁・昨日・今日・合計
	$fig1 = 3;
	$fig2 = 3; 
	$fig3 = 6;
 
	//--------------設定ここまで----------------
 
	//  ロック
	$fp_lock = fopen($lock_file, "r");
	flock($fp_lock, LOCK_EX);
 
	$today_date = date("Ymd");
	$yes_date =  date("Ymd", time() - 24*60*60);
 
	$count_buf = file($count_file);
	if ($count_buf == false) echo 'file error '.$count_file;
	$ip = $_SERVER['REMOTE_ADDR'];
 
	//  変数を展開
	list($count_date, $yes_count, $today_count, $total_count, $ip_buf) = explode("|", $count_buf[0]);
	$ip_list = explode(",", $ip_buf);
	if (count($ip_list) == 0) $ip_list = array();
 
	$update = false;
	$ip_count = true;
	//  IPの重複チェック
	if ($ipcheck && $count_date == $today_date) {
		$ipn = 0;
		foreach ($ip_list as $ip_old) {
			$ip_old_ip = explode("#", $ip_old);
			if ($ip == $ip_old_ip[0]) {
				$ip_count = false;
				//  IPが末尾(最新アクセス)でなければ末尾に
				if ($ipn < count($ip_list)-1) {
					unset($ip_list[$ipn]);
					$ip_list[] = $ip_old;
					$update = true;
				}
				break;
			}
			$ipn += 1;
		}
	}
 
	//  adminでログインされてたらならカウントしない
	if ($INFO['isadmin']) {
		$update = false;
		$ip_count = false;
	}
 
	//  カウント
	if ($ip_count) {
		//  crawler弾き
		$crawler = false;
		$ip_host = gethostbyaddr($ip);
		$ip_agent = $_SERVER['HTTP_USER_AGENT'];
		if (strpos($ip_agent, "Yahoo! Slurp") != false) $crawler = true;
		if (strpos($ip_agent, "Googlebot") != false) $crawler = true;
		//
		if (!$crawler) {
			if ($count_date == $today_date) {
				$today_count++;
			} else {
				$yes_count = ($count_date == $yes_date) ? $today_count : 0;
				$today_count = 1;
				unset($ip_list);
				$ip_list = array();
			}
			$update = true;
			$total_count++;
			$ip_list[] = $ip;
			if (count($ip_list) > $ipcheck_max) array_shift($ip_list);
		}
	}
 
	//  カウントファイル更新
	if ($update) {
		$ip_buf = implode(",", array_values($ip_list));
		$buf = implode("|", array($today_date, $yes_count, $today_count, $total_count, $ip_buf));
 
		$fp = fopen($count_file, "w");
		fputs($fp, $buf);
		fclose($fp);
	}
	//  ロック解除
	fclose($fp_lock);
 
	//  桁数整形
	$yes_count_str   = sprintf("%0".$fig1."d", $yes_count);
	$today_count_str = sprintf("%0".$fig2."d", $today_count);
	$total_count_str = sprintf("%0".$fig3."d", $total_count);
	$title = "Total:{$total_count_str} Today:{$today_count_str} Yesterday:{$yes_count_str}";
 
	//  タグを取得
	$yes_count_str   = outhtml($yes_count_str,   $yes_counter_path);
	$today_count_str = outhtml($today_count_str, $today_counter_path);
	$total_count_str = outhtml($total_count_str, $total_counter_path);
	$size = getimagesize($today_img_path);
	$today_img = "&nbsp;<img src=\"{$today_img_path}\" alt=\"today\" {$size[3]}>";
	$size = getimagesize($yes_img_path);
	$yes_img = "&nbsp;<img src=\"{$yes_img_path}\" alt=\"yesterday\" {$size[3]}>";
 
	echo '<a title="'.$title.'">'.$total_count_str . $today_img . $today_count_str . $yes_img . $yes_count_str.'</a>';
}
 
//  カウント数とパスを与えて、IMGタグを返す
function outhtml($f_cnt,$c_path) {
	$size = getimagesize($c_path. "0.gif");  //  0.gifからwidthとheight取得
	for($i = 0; $i < strlen($f_cnt); $i++) { //  桁数分だけループ
		$n = substr($f_cnt, $i, 1);          //  左から一桁ずつ取得
		$i_tag .= "<img src=\"{$c_path}{$n}.gif\" alt=\"{$n}\" {$size[3]}>";
	}
 
	return $i_tag;
}
?>

/lib/tpl/arctic/footer.html

フッターの一番左に呼出しコードを追加しただけ。

/lib/tpl/arctic/footer.html
<?php
/**
 * Example footer include
 *
 * This file shows you how to use the include hooks. However I recommend to
 * create your own complete new template instead. 
 */
require_once(DOKU_INC.'lib/counter/counter.php');
?>
<div align="center" class="footerinc">
  <?php site_counter()?>
 
  <?php tpl_license('button', true)?>
 
  <a target="_blank" href="http://www.chimeric.de" title="www.chimeric.de"><img src="<?php echo DOKU_TPL?>images/button-chimeric-de.png" width="80" height="15" alt="www.chimeric.de" border="0" /></a>
 
  <a target="_blank" href="http://jigsaw.w3.org/css-validator/check/referer" title="Valid CSS"><img src="<?php echo DOKU_TPL?>images/button-css.png" width="80" height="15" alt="Valid CSS" border="0" /></a>
 
  <a target="_blank" href="http://wiki.splitbrain.org/wiki:dokuwiki" title="Driven by DokuWiki"><img src="<?php echo DOKU_TPL?>images/button-dw.png" width="80" height="15" alt="Driven by DokuWiki" border="0" /></a>
 
  <a target="_blank" href="http://www.firefox-browser.de" title="do yourself a favour and use a real browser - get firefox"><img src="<?php echo DOKU_TPL?>images/button-firefox.png" width="80" height="15" alt="do yourself a favour and use a real browser - get firefox!!" border="0" /></a>
 
  <a target="_blank" href="<?php echo DOKU_BASE?>feed.php" title="Recent changes RSS feed"><img src="<?php echo DOKU_TPL?>images/button-rss.png" width="80" height="15" alt="Recent changes RSS feed" border="0" /></a>
 
  <a target="_blank" href="http://validator.w3.org/check/referer" title="Valid XHTML 1.0"><img src="<?php echo DOKU_TPL?>images/button-xhtml.png" width="80" height="15" alt="Valid XHTML 1.0" border="0" /></a>
</div>

~~DISCUSSION~~