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
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 11
滕勇志

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

6年前 评论

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

6年前 评论

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

6年前 评论

: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` # 统计行数
6年前 评论

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

6年前 评论

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

6年前 评论

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

5年前 评论

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

5年前 评论

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

4年前 评论