编程笔记

编程笔记

对网站统计IP的深入挖掘php实例。
2025-02-28

借助一些第三方的 IP 地址库和用户代理解析工具。以下是对前面代码的扩展,通过集成相关功能来实现对 IP 来源和设备的分析。


我们将使用 geoip2 库来获取 IP 地址的地理位置信息,使用 browscap 库来解析用户代理字符串以获取设备信息。首先确保你的服务器安装了 geoip2 和 browscap 扩展(或通过 Composer 安装相关的 PHP 库)。


以下是修改后的代码:

1. 记录用户访问信息的文件 log_user_visits.php


收起
php
<?php// 获取用户的 IP 地址$user_ip = $_SERVER['REMOTE_ADDR'];// 获取当前访问的链接$current_url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";// 获取当前访问时间$visit_time = date('Y-m-d H:i:s');$visit_date = date('Y-m-d', strtotime($visit_time));// 获取用户代理字符串$user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';try {
    // 引入 geoip2 库(假设你已通过 Composer 安装并正确引入)
    require_once('vendor/autoload.php');
    $reader = new \GeoIp2\Database\Reader('/path/to/GeoLite2-City.mmdb'); // 替换为实际的 GeoIP2 数据库文件路径
    $record = $reader->city($user_ip);
    $country = $record->country->name;
    $city = $record->city->name;} catch (\Exception $e) {
    $country = '未知';
    $city = '未知';}// 解析用户代理字符串获取设备信息(假设你已通过 Composer 安装并正确引入 browscap 库)try {
    $browscap = new \Browscap\Browscap('/path/to/browscap.ini'); // 替换为实际的 browscap.ini 文件路径
    $browserData = $browscap->getBrowser($user_agent);
    $device_type = $browserData['DeviceType'] ?? '未知';
    $browser_name = $browserData['Browser'] ?? '未知';
    $browser_version = $browserData['Version'] ?? '未知';} catch (\Exception $e) {
    $device_type = '未知';
    $browser_name = '未知';
    $browser_version = '未知';}// 记录访问信息到日志文件$log_file = 'user_visit_log.txt';$log_entry = "{$visit_date} - {$visit_time} - {$user_ip} - {$country} - {$city} - {$device_type} - {$browser_name} - {$browser_version} - {$current_url}\n";file_put_contents($log_file, $log_entry, FILE_APPEND);?>

代码解释


  • 获取用户的 IP 地址、访问链接、访问时间和用户代理字符串。

  • 使用 geoip2 库从 IP 地址获取国家和城市信息。如果获取失败,设置为 未知

  • 使用 browscap 库解析用户代理字符串,获取设备类型、浏览器名称和版本信息。如果解析失败,设置为 未知

  • 将所有信息拼接成日志记录,写入到 user_visit_log.txt 文件中。

2. 统计用户访问信息的文件 analyze_user_visits.php


收起
php
<?php// 统计用户访问次数和相关信息function count_user_visits() {
    $log_file = 'user_visit_log.txt';
    if (!file_exists($log_file)) {
        return [];
    }

    $lines = file($log_file, FILE_IGNORE_NEW_LINES);
    $daily_user_counts = [];
    $daily_user_url_counts = [];
    $daily_unique_ips = [];
    $daily_location_counts = [];
    $daily_device_counts = [];

    foreach ($lines as $line) {
        $parts = explode(' - ', $line);
        if (count($parts) >= 9) {
            $visit_date = $parts[0];
            $user_ip = $parts[2];
            $country = $parts[3];
            $city = $parts[4];
            $device_type = $parts[5];
            $browser_name = $parts[6];
            $browser_version = $parts[7];
            $url = $parts[8];

            // 统计每日用户总访问次数
            if (!isset($daily_user_counts[$visit_date])) {
                $daily_user_counts[$visit_date] = [];
            }
            if (!isset($daily_user_counts[$visit_date][$user_ip])) {
                $daily_user_counts[$visit_date][$user_ip] = 0;
            }
            $daily_user_counts[$visit_date][$user_ip]++;

            // 统计每日用户访问每个链接的次数
            if (!isset($daily_user_url_counts[$visit_date])) {
                $daily_user_url_counts[$visit_date] = [];
            }
            if (!isset($daily_user_url_counts[$visit_date][$user_ip])) {
                $daily_user_url_counts[$visit_date][$user_ip] = [];
            }
            if (!isset($daily_user_url_counts[$visit_date][$user_ip][$url])) {
                $daily_user_url_counts[$visit_date][$user_ip][$url] = 0;
            }
            $daily_user_url_counts[$visit_date][$user_ip][$url]++;

            // 统计每日不同 IP 的数量
            if (!isset($daily_unique_ips[$visit_date])) {
                $daily_unique_ips[$visit_date] = [];
            }
            if (!in_array($user_ip, $daily_unique_ips[$visit_date])) {
                $daily_unique_ips[$visit_date][] = $user_ip;
            }

            // 统计每日不同地理位置的访问次数
            if (!isset($daily_location_counts[$visit_date])) {
                $daily_location_counts[$visit_date] = [];
            }
            $location_key = "{$country} - {$city}";
            if (!isset($daily_location_counts[$visit_date][$location_key])) {
                $daily_location_counts[$visit_date][$location_key] = 0;
            }
            $daily_location_counts[$visit_date][$location_key]++;

            // 统计每日不同设备的访问次数
            if (!isset($daily_device_counts[$visit_date])) {
                $daily_device_counts[$visit_date] = [];
            }
            $device_key = "{$device_type} - {$browser_name} - {$browser_version}";
            if (!isset($daily_device_counts[$visit_date][$device_key])) {
                $daily_device_counts[$visit_date][$device_key] = 0;
            }
            $daily_device_counts[$visit_date][$device_key]++;
        }
    }

    return [
        'daily_user_counts' => $daily_user_counts,
        'daily_user_url_counts' => $daily_user_url_counts,
        'daily_unique_ip_counts' => array_map('count', $daily_unique_ips),
        'daily_location_counts' => $daily_location_counts,
        'daily_device_counts' => $daily_device_counts
    ];}// 调用统计函数$stats = count_user_visits();// 输出统计结果echo "<h2>每日用户总访问次数统计</h2>";foreach ($stats['daily_user_counts'] as $date => $user_counts) {
    echo "<h3>日期: {$date}</h3>";
    foreach ($user_counts as $user_ip => $count) {
        echo "<p>IP: {$user_ip}, 访问次数: {$count}</p>";
    }}echo "<h2>每日用户访问链接详细统计</h2>";foreach ($stats['daily_user_url_counts'] as $date => $user_url_counts) {
    echo "<h3>日期: {$date}</h3>";
    foreach ($user_url_counts as $user_ip => $urls) {
        echo "<p>IP: {$user_ip}</p>";
        foreach ($urls as $url => $count) {
            echo "<p>  链接: {$url}, 访问次数: {$count}</p>";
        }
    }}echo "<h2>每日不同 IP 总数统计</h2>";foreach ($stats['daily_unique_ip_counts'] as $date => $count) {
    echo "<p>日期: {$date}, 不同 IP 的总数: {$count}</p>";}echo "<h2>每日不同地理位置访问次数统计</h2>";foreach ($stats['daily_location_counts'] as $date => $location_counts) {
    echo "<h3>日期: {$date}</h3>";
    foreach ($location_counts as $location => $count) {
        echo "<p>地理位置: {$location}, 访问次数: {$count}</p>";
    }}echo "<h2>每日不同设备访问次数统计</h2>";foreach ($stats['daily_device_counts'] as $date => $device_counts) {
    echo "<h3>日期: {$date}</h3>";
    foreach ($device_counts as $device => $count) {
        echo "<p>设备: {$device}, 访问次数: {$count}</p>";
    }}?>

代码解释


  • count_user_visits 函数

    • 读取日志文件的每一行,解析出日期、IP 地址、国家、城市、设备类型、浏览器名称、浏览器版本和访问链接等信息。

    • 统计每日每个 IP 的访问次数、每个 IP 对不同链接的访问次数、每日不同 IP 的数量、每日不同地理位置的访问次数以及每日不同设备的访问次数。

  • 输出统计结果

    • 分别输出每日用户总访问次数、每日用户访问链接详细信息、每日不同 IP 总数、每日不同地理位置访问次数和每日不同设备访问次数的统计结果。

使用方法


  1. 确保已安装 geoip2 和 browscap 库(或扩展),并正确配置相关的数据库文件路径(如 GeoLite2-City.mmdb 和 browscap.ini)。

  2. 将 log_user_visits.php 文件插入到网站的底部,例如在网站的 footer.php 文件中添加以下代码:


收起
php
<?php include('log_user_visits.php'); ?>


这样每次有用户访问网站时,都会记录包含 IP 来源和设备信息的访问日志。
3. 当需要查看统计结果时,直接访问 analyze_user_visits.php 文件,即可看到详细的统计信息。

注意事项


  • GeoLite2-City.mmdb 和 browscap.ini 文件需要定期更新,以保证获取的信息准确。

  • 确保服务器对相关文件有读取权限。

  • 对于日志文件较大的情况,读取和统计操作可能会影响性能,可以考虑定期清理日志文件或使用数据库来存储统计信息。