// +---------------------------------------------------------------------- declare (strict_types = 1); namespace addon\blog\model; use ywxapp\model\BaseModel; class BlogVisit extends BaseModel { // 设置数据表名 protected $name = 'blog_visit'; // 设置主键 protected $pk = 'id'; // 自动写入时间戳 protected $autoWriteTimestamp = 'int'; protected $createTime = 'create_at'; protected $updateTime = false; // 定义允许写入的字段 protected $allowField = [ 'ip', 'url', 'referer', 'user_agent' ]; // 设置字段类型 protected $type = [ 'create_at' => 'int' ]; // 获取客户端IP地址 public static function getClientIp() { $ip = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0'; if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); $ip = trim($ips[0]); } return $ip; } // 记录访问 public static function record($url, $referer = '', $userAgent = '') { $visit = new self(); $visit->ip = self::getClientIp(); $visit->url = $url; $visit->referer = $referer ?: request()->server('HTTP_REFERER', ''); $visit->user_agent = $userAgent ?: request()->server('HTTP_USER_AGENT', ''); $visit->save(); } // 获取访问统计 public static function getStats($days = 7) { $startTime = time() - ($days * 86400); // 总访问量 $total = self::where('create_at', '>=', $startTime)->count(); // 独立访客 $uniqueVisitors = self::where('create_at', '>=', $startTime) ->distinct(true) ->field('ip') ->count(); // 热门页面 $hotPages = self::where('create_at', '>=', $startTime) ->field('url, COUNT(*) as count') ->group('url') ->order('count', 'desc') ->limit(10) ->select(); // 访问趋势 $trend = []; for ($i = 0; $i < $days; $i++) { $date = date('Y-m-d', time() - ($i * 86400)); $count = self::whereDay('create_at', $date)->count(); $trend[$date] = $count; } return [ 'total' => $total, 'unique_visitors' => $uniqueVisitors, 'hot_pages' => $hotPages, 'trend' => $trend ]; } // 获取真实IP(考虑代理) public static function getRealIp() { $ip = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0'; if (isset($_SERVER['HTTP_CLIENT_IP']) && filter_var($_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP)) { $ip = $_SERVER['HTTP_CLIENT_IP']; } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); foreach ($ips as $candidate) { $candidate = trim($candidate); if (filter_var($candidate, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { $ip = $candidate; break; } } } return $ip; } }