Laravel 10 行代码实现简单的网站 pv uv 统计

最近在优化博客呀,想做一个统计网站 pv uv 的功能,虽然有第三的统计平台再用,但还是想自己写一个啊。

其实统计的数据非常简单,就是网站的访问量丶访客量。

        public function __construct()
        {
            Funcs::setUV();
            DB::table('visiter')->where('id',1)->increment('pv');
        }

我还特意设计了两张简单的表来记录数据。

记录访客

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for my_uvs
-- ----------------------------
DROP TABLE IF EXISTS `my_uvs`;
CREATE TABLE `my_uvs`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `ip` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `last_time` int(10) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = MyISAM AUTO_INCREMENT = 34 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

记录 pv uv

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for my_visiter
-- ----------------------------
DROP TABLE IF EXISTS `my_visiter`;
CREATE TABLE `my_visiter`  (
  `id` int(10) NOT NULL DEFAULT 0,
  `pv` int(10) NULL DEFAULT NULL,
  `uv` int(10) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = MyISAM CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Fixed;

SET FOREIGN_KEY_CHECKS = 1;

访问量

初始化 visiter 表,新增一个就行 。
页面每访问一次,就自增 1.

    DB::table('visiter')->where('id',1)->increment('pv');

访客量

访客量我是以 ip 记录的,每个 ip 在 24 小时内访问只记录一次,所有才有了 last_time 字段,用访问时间做对比就行了。

        public static function setUV()
        {
            $ip = request()->ip();
            $uv = DB::table('uvs')->where('ip',$ip)->first('*');
            $uv = self::toArray($uv);
            if ($uv === null){
                DB::table('uvs')->insert(['ip'=>$ip,'last_time'=>time()]);
                DB::table('visiter')->where('id',1)->increment('uv');
                return true;
            }
            if ($uv['last_time'] + 86400 < time()){
                DB::table('uvs')->where('ip',$uv['ip'])->update(['last_time'=>time()]);
                DB::table('visiter')->where('id',1)->increment('uv');
                return true;
            }
            return 0;
        }

总结

可能这种方法统计的很不全面,但是在设计方面还算是比较合理的。
这种统计代码放在中间件里实现更精简更合理。
以 ip 来记录访客量,到后面数据肯定会比较大,这到时候用 artisan 计划任务清理就行。
代码贵在分享,本人较菜,勿喷~~~

本作品采用《CC 协议》,转载必须注明作者和本文链接
By: Laravel-China NiZerin Blog: nizer.in
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 11
小滕

不建议直接操作数据库记录,可以先记录到redis在定时同步数据。 :+1:

5年前 评论

可以新建一个统计的中间件,独立负责这个统计的功能。

5年前 评论

@AlicFeng 是的,有想过的 ,可以实现 :smirk:

5年前 评论

:joy: 单纯的 PV UV 通过分析 nginxaccess_log 就可以了,每天写个计划任务,分析前一天的日志,存储起来。

PV : egrep -v '\.jpg|\.png|\.gif|\.css|\.jpeg|\.js' access_log_path | wc -l

UV :

egrep -v '\.jpg|\.png|\.gif|\.js|\.css|\.jpeg' access_log_path\
awk '{print $1}' |\ #将 access_log 每行第一个(即 IP )打印
uniq | \ #去重
wc -l` # 统计行数
5年前 评论

之前看过一个教程,用golang的协程去实现这个功能。你这个自己的网站,访问量不大还行。

5年前 评论

个人网站流量不大,这种办法还是比较 ok 的,流量大了肯定就不行的 :+1:

5年前 评论

UV用ip区分?在移动网络下每次刷新ip都是会变的

4年前 评论

@Okok 本人学才疏浅,如果 ip 一直改变的话我觉得用 session 或者 cookie 也是可以的

4年前 评论

局域网ip 都是相同的,这样统计出来了UV 是不太准的 不知道还有啥办法不

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!