王新阳

wangxinyang

PHP生成网站访问日志

以下两个文件放在根目录 wxylog 文件夹中

wxylog_class.php

<?php
/*
 * 生成网站访问日志
 * 调用方法:在入口页程序中加入 include('/wxylog/wxylog_class.php'); new wxylog_class();
 */
final class wxylog_class{
	private $path='';
	private $uri ='';
	public function __construct(){
		$this->path = dirname(__FILE__).'/log/';
		if(!file_exists($this->path) && !mkdir($this->path))return FALSE; //文件夹创建失败
		$this->uri = $this->server('REQUEST_URI');
		if(! $this->allow())return FALSE; //是否需要记录
		$this->log();
	}
	private function server($para){
		$para = strtoupper($para);
		return isset($_SERVER[$para]) ? str_replace(chr(9), chr(32), $_SERVER[$para]) : '';
	}
	private function log(){
		$file = $this->path.date('Ymd').'.log';
		$str = date('Y-m-d H:i:s');
		foreach(array('REMOTE_ADDR', 'REQUEST_METHOD', 'REQUEST_URI', 'HTTP_USER_AGENT', 'HTTP_REFERER') as $item){
			$str .= chr(9).$this->server($item);
		}
		$str .= "\n";
		//写入访问日志
		@file_put_contents($file, $str, FILE_APPEND);
		
		//获取蜘蛛类型
		$array = array('Baiduspider', 'Sogou web spider', 'Googlebot', 'bingbot', 'Sosospider', 'yisouspider', 'Yahoo! Slurp', '360Spider');
		$robot = '';
		foreach($array as $item){
			if(strpos(strtolower($this->server('HTTP_USER_AGENT')), strtolower($item)) !== FALSE){
				$robot = $item;
				break;
			}
		}

		$file = $this->path.date('Ymd').'.php';
		$array = @include $file;
		is_array($array) OR $array=array('total'=>0, 'not_robot'=>0, 'robot'=>array(), 'request_method'=>array(), 'page'=>array('index'=>0, 'inside'=>0, 'http_referer'=>0)); //访问总数、非蜘蛛访问数、各蜘蛛访问数、受访页面(首页、内页、通过其他链接进入)
		//访问总数
		$array['total'] += 1;
		//请求方式
		if($method = $this->server('REQUEST_METHOD')){
			isset($array['request_method'][$method]) OR $array['request_method'][$method]=0;
			$array['request_method'][$method]+=1;
		}
		//首页/内页访问数
		$array['page'][preg_match('/^\/(index.php)?(\/?\?.+)?$/i', $this->uri) ? 'index' : 'inside'] += 1;
		//通过其他链接进入数
		$this->server('HTTP_REFERER') AND $array['page']['http_referer'] += 1;
		//更新蜘蛛访问数
		if($robot){
			isset($array['robot'][$robot]) OR $array['robot'][$robot]=0;
			$array['robot'][$robot]+=1;
		}else{
			$array['not_robot'] += 1;
		}
		$code = "<?php\n return ". var_export($array, true) .";\n";
		//写入统计
		@file_put_contents($file, $code);
		
		//禁止访问某些页面
		$this->deny($robot);
	}
	//禁止访问某些页面,根据实际需要单独开发
	private function deny($robot){
		//比如禁止百度访问搜索页
		//if(strpos($this->uri, 'search')!==FALSE && $robot=='Baiduspider')exit('ACCESS DENIED');
	}
	//是否记录当前uri,根据实际需要单独开发
	private function allow(){
	/*
		//比如不记录验证码生成程序
		//以下均为正则表达式
		$array = array(
			'\/verifycode'
		);
		foreach($array as $item){
			if(preg_match('/^\/(index.php)?'.$item.'/i', $this->uri))return FALSE;
		}
	*/
		return true;
	}
}

 

wxylog_view.php

<?php
/*
 * 日志查看程序 wxy 20180106
 * 当前页面必须放在 /wxylog 目录下
 * /wxylog/wxylog_class.php 在入口页程序中加入以下代码调用: include('/wxylog/wxylog_class.php'); new wxylog_class();
 * /wxylog/wxylog_view.php
 * 自动生成的其他日志文件,以年月日8位数字开头。如 20180106.log, 20180106.php
 */

define('LOG_PATH', dirname(__FILE__).'/log/');
switch($_SERVER['REQUEST_METHOD']){
	case 'GET':
		if(! isset($_COOKIE['wxylog']) || $_COOKIE['wxylog'] !== 'ok'){
			show_login();
			exit;
		}
		if(isset($_GET['date'])){ //获取日志详情
			show_log();
		}else{
			show_list(); //显示列表
		}
		break;
	case 'POST':
		if(isset($_POST['pwd']) && sha1($_POST['pwd'])==='59b331507615f9f98bf17558ee678cafdbdb5bfe'){
			setcookie('wxylog', 'ok');
			header('Location: '.$_SERVER['REQUEST_URI']);
			exit;
		}elseif(isset($_POST['date'])){
			delete_log();
		}
		break;
	default:
		exit('ACCESS DENIED');
}

function show_log(){
	$date = $_GET['date'];
	if(! preg_match('/^20\d{6}$/', $date))exit('');
	echo '<pre style="font:14px/1.5 Arial;">';
	exit(@file_get_contents(LOG_PATH.$date.'.log'));
}

function show_data(){
	$array = @scandir(LOG_PATH, 1);
	if(! $array)return FALSE;
	foreach($array as $file){
		if(is_dir($file) || !preg_match('/^20\d{6}\.php$/', $file))continue;
		$data = @include LOG_PATH.$file;
		is_array($data) AND echo_html($file, $data);
	}
}

function format_bytes($size, $delimiter = '') {
	$units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
	for ($i = 0; $size >= 1024 && $i < 5; $i++) $size /= 1024;
	return round($size, 2) . $delimiter . $units[$i];
}

function delete_log(){
	$date = $_POST['date'];
	if(preg_match('/^20\d{6}$/', $date)){
		if(@unlink(LOG_PATH.$date.'.log')){
			exit(@unlink(LOG_PATH.$date.'.php') ? 'success' : 'fail');
		}else{
			exit('fail');
		}
	}else{
		exit('ACCESS DENIED');
	}
}

function echo_html($file, $data){
	if(! isset($data['total']))return;
	$date = substr($file,0,8);
	echo '<div class="col-sm-4 col-md-3"><ul class="list-group"><li class="list-group-item active"><strong>', $date, '</strong><div class="pull-right"><a href="javascript:;" data-del-file="', $date, '">删除</a>   <a target="_blank" href="?date=', $date, '">浏览</a></div></li>';
	echo '<li class="list-group-item">访问次数 <kbd>', $data['total'], '</kbd></li>';
	echo '<li class="list-group-item">搜索引擎 <kbd>', $data['total']-$data['not_robot'], '</kbd></li>';
	echo '<li class="list-group-item">正常访问 <kbd>', $data['not_robot'], '</kbd></li>';
	echo '<li class="list-group-item list-group-item-success"><strong>访问页面</strong></li>';
	echo '<li class="list-group-item">首页 <kbd>', $data['page']['index'], '</kbd></li>';
	echo '<li class="list-group-item">内页 <kbd>', $data['page']['inside'], '</kbd></li>';
	echo '<li class="list-group-item">通过其他链接访问 <kbd>', $data['page']['http_referer'], '</kbd></li>';
	echo '<li class="list-group-item list-group-item-info"><strong>请求方式</strong></li>';
	arsort($data['request_method']);
	foreach($data['request_method'] as $key=>$val){
		echo "<li class=\"list-group-item\">{$key} <kbd>{$val}</kbd></li>";
	}
	if($data['total'] != $data['not_robot']){
		echo '<li class="list-group-item list-group-item-warning"><strong>搜索引擎</strong></li>';
		arsort($data['robot']);
		foreach($data['robot'] as $key=>$val){
			echo "<li class=\"list-group-item\">{$key} <kbd>{$val}</kbd></li>";
		}
	}
	echo '<li class="list-group-item list-group-item-danger">日志文件 <kbd>', format_bytes(filesize(LOG_PATH.$date.'.log')), '</kbd></li>';
	echo '</ul></div>';
}

function show_list(){
?><!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>数据统计</title>
<link href="http://apps.bdimg.com/libs/bootstrap/3.3.4/css/bootstrap.css" rel="stylesheet">
<style>
body,kbd{font-size:medium;}
a{color:#bce8f1;}
.container{padding-top:20px;}
</style>
</head>
<body>
<div class="container">
	<div class="row">
<?php show_data(); ?>
	</div>
</div>
<script src="http://apps.bdimg.com/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
$('a[data-del-file]').click(function(){
	if(!confirm('确定要删除此日志吗?'))return;
	$.post('', {date:$(this).attr('data-del-file')}, function(text){
		if(text=='success'){
			alert('删除成功');
			self.location.reload();
		}else{
			alert('删除失败');
		}
	}, 'text');
});
</script>
</body>
</html>
<?php
}

function show_login(){
?><!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>Log System</title>
<link href="http://apps.bdimg.com/libs/bootstrap/3.3.4/css/bootstrap.css" rel="stylesheet">
<script src="http://apps.bdimg.com/libs/jquery/1.11.3/jquery.min.js"></script>
<style>
body{background:#333;}
a{font-size:large !important;cursor:pointer;}
.mybox{margin:0 auto;width:300px;}
</style>
</head>
<body>
<div class="mybox">
<form class="form-inline" method="post">
	<div class="form-group form-group-lg">
		<div class="input-group">
			<input type="password" name="pwd" class="form-control" placeholder="password" autocomplete="new-password" autofocus>
			<a class="input-group-addon" onclick="$('form')[0].submit()">Login</a>
		</div>
	</div>
</form>
</div>
<script>$('.mybox').css('margin-top', $(window).height()/3);</script>
</body>
</html>
<?php
}

2018-01-06
2024-05-03 星期五 农历三月二十五