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 }