返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >PHP四种统计在线人数方式详细介绍
  • 237
分享到

PHP四种统计在线人数方式详细介绍

2024-04-02 19:04:59 237人浏览 泡泡鱼
摘要

目录1 用表统计方式2 使用 Redis 有序集合实现在线人数统计3 使用 hyperloglog 做统计4 使用 bitmap 统计1 用表统计方式 用数据表统计在线人数,这种方式

1 用表统计方式

用数据表统计在线人数,这种方式只能用在并发量不大的情况下。

首先我们先新建表:user_login

编辑

user_login 表

模拟用户登录,不存在用户就存入表,存在的则更新登录信息

// 客户端唯一的识别码
$client_id = session()->getId();
//用户是否已存在
$user = DB::table('user_login')
    ->where('token', $client_id)
    ->first();
//不存在则插入数据
if (empty($user)) {
    $data = [
        'token' => $client_id,
        'username' => 'user_' . $client_id, // 模拟用户
        'uid' => mt_rand(10000000, 99999999),   //模拟用户id
        'create_time' => date('Y-m-d H:i:s'),
        'update_time' => date('Y-m-d H:i:s')
    ];
    DB::table('user_login')->insert($data);
} else {    
    // 存在则更新用户登录信息
    DB::table('user_login')
     ->where('token', $client_id)
     ->update([
          'update_time' => date('Y-m-d H:i:s')
      ]);
}

这里还需要定期清理无任何操作的用户,假如用户一个小时内无任何操作,我们可以记为无效用户

代码如下:

// 客户端唯一的识别码
$client_id = session()->getId();
//用户是否已存在
$user = DB::table('user_login')
    ->where('token', $client_id)
    ->first();
//不存在则插入数据
if (empty($user)) {
    $data = [
        'token' => $client_id,
        'username' => 'user_' . $client_id, // 模拟用户
        'uid' => mt_rand(10000000, 99999999),   //模拟用户id
        'create_time' => date('Y-m-d H:i:s'),
        'update_time' => date('Y-m-d H:i:s')
    ];
    DB::table('user_login')->insert($data);
} else {    
    // 存在则更新用户登录信息
    DB::table('user_login')
     ->where('token', $client_id)
     ->update([
          'update_time' => date('Y-m-d H:i:s')
      ]);
}

我们可以实现的功能:

1)当前在线人数

2)某时间段内在线人数

3)最新上线的用户

4)指定用户是否在线

// 可实现功能一:当前总共在线人数
$c = DB::table('user_login')->count();
echo '当前在线人数:' . $c . '<br />';
// 可实现功能二:某时间段内在线人数
$begin_date = '2020-08-13 09:00:00';
$end_date = '2020-08-13 18:00:00';
$c = DB::table('user_login')
    ->where('create_time', '>=', $begin_date)
    ->where('create_time', '<=', $end_date)
    ->count();
echo $begin_date . '-' . $end_date . '在线人数:' . $c . '<br />';
// 可实现功能三:最新上线的用户
$newest = DB::table('user_login')
    ->orderBy('create_time', 'DESC')
    ->limit(10)
    ->get();
echo '最新上线的用户有:';
foreach ($newest as $value) {
    echo $value->username . ' ';
}
echo '<br />';
// 可实现功能四:指定用户是否在线
$username = 'user_1111';
$online = DB::table('user_login')
    ->where('username', $username)
    ->exists();
echo $username . ($online ? '在线' : '不在线');

2 使用 redis 有序集合实现在线人数统计

因为是内存中,所以效率很高,可以统计某个时间段内的在线人数,可以做各种聚合操作。但是如果在线人数比较多的情况下,会比较占用内存。还有一点:

无法通过用户操作时间清除掉无效用户,只有手动登出的用户才会从集合中删除。

代码如下:

// 客户端唯一的识别码
$client_id = session()->getId();
echo $client_id . '<br />';
// 按日期生成key
$day = date('Ymd');
$key = 'online:' . $day;
// 是否在线
$is_online = Redis::zScore($key, $client_id);
if (empty($is_online)) {    // 不在线,加入当前客户端
    Redis::zAdd($key, time(), $client_id);
}
// 可实现功能一:当前总共在线人数
$c = Redis::zCard($key);
echo '当前在线人数:' . $c . '<br />';
// 可实现功能二:某时间段内在线人数
$begin_date = '2020-08-13 09:00:00';
$end_date = '2020-08-13 18:00:00';
$c = Redis::zCount($key, strtotime($begin_date), strtotime($end_date));
echo $begin_date . '-' . $end_date . '在线人数:' . $c . '<br />';
// 可实现功能三:最新上线的用户,时间从小到大排序
$newest = Redis::zRangeByScore($key, '-inf', '+inf', ['limit' => [0, 50]]);
echo '最新上线的用户有:';
foreach ($newest as $value) {
    echo $value . ' ';
}
echo '<br />';
// 可实现功能四:指定用户是否在线
$username = $client_id;
$online = Redis::zScore($key, $client_id);;
echo $username . ($online ? '在线' : '不在线') . '<br />';
// 可实现功能五:昨天和今天都上线的客户
$yestoday = Carbon::yesterday()->toDateString();
$yes_key = str_replace('-', '', $yestoday);
$members = [];
Redis::pipeline(function ($pipe) use ($key, $yes_key, &$members) {
    Redis::zinterstore('new_key', [$key, $yes_key], ['aggregate' => 'min']);
    $members = Redis::zRangeByScore('new_key', '-inf', '+inf', ['limit' => [0, 50]]);
    //dump($members);
});
echo '昨天和今天都上线的用户有:';
foreach ($members as $value) {
    echo $value . ' ';
}

3 使用 hyperloglog 做统计

跟有序集合方式不同,hyperloglog 十分节约空间,但是实现的功能也非常单一,只能统计在线人数,不能实现其余的任何功能。

Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。

在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。

// note HyperLogLog 只需要知道在线总人数
for ($i=0; $i < 6; $i++) {
    $online_user_num = mt_rand(10000000, 99999999);     //模拟在线人数
    var_dump($online_user_num);
    for ($j=1; $j < $online_user_num; $j++) { 
        $user_id = mt_rand(1, 100000000);
        $redis->pfadd('002|online_users_day_'.$i, [$user_id]);
    }
}
$count = 0;
for ($i=0; $i < 3; $i++) { 
    $count += $redis->pfcount('002|online_users_day_'.$i);
    print_r($redis->pfcount('002|online_users_day_'.$i). "\n");
}
var_dump($count);
//note  3 days total online num
var_dump($redis->pfmerge('002|online_users_day_both_3', ['002|online_users_day_0', '002|online_users_day_1', '002|online_users_day_2']));
var_dump($redis->pfcount('002|online_users_day_both_3'));

这种方案仅仅只能统计出某个时间段在线人数的总量, 对在线用户的名单却无能为力,但是却挺节省内存的,对统计数据要求不多情况下 ,我们便可以考虑这种方案

4 使用 bitmap 统计

bitmap 就是通过一个 bit 位来表示某个元素对应的值或者状态,其中的 key 就是对应元素本身。我们知道 8 个 bit 可以组成一个 Byte,所以 bitmap 本身会极大的节省储存空间。

bitmap 常用来做比如用户签到、活跃用户、在线用户等功能。

代码如下

// 模拟当前用户
$uid = request('uid');
$key = 'online_bitmap_' . date('Ymd');
// 设置当前用户在线
Redis::setBit($key, $uid, 1);
// 可实现功能1:在线人数
$c = Redis::bitCount($key);
echo '在线人数:' . $c . '<br />';
// 可实现功能2:指定用户是否在线
$online = Redis::getBit($key, $uid);
echo $uid . ($online ? '在线' : '不在线') . '<br />';
// 可实现功能3:昨天和今天均上线的用户总数
$yestoday = Carbon::yesterday()->toDateString();
$yes_key = str_replace('-', '', $yestoday);
$c = 0;
Redis::pipeline(function ($pipe) use ($key, $yes_key, &$c) {
    Redis::bitOp('AND', 'yest', $key, $yes_key);
    $c = Redis::bitCount('yest');
});
echo '昨天和今天都上线的用户数量有:' . $c . '<br />';

bitmap 消耗的内存空间不多, 统计的信息却挺多的,这种方案是值得推荐一下的。

到此这篇关于PHP四种统计在线人数方式详细介绍的文章就介绍到这了,更多相关php统计在线人数内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: PHP四种统计在线人数方式详细介绍

本文链接: https://lsjlt.com/news/168007.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • PHP四种统计在线人数方式详细介绍
    目录1 用表统计方式2 使用 redis 有序集合实现在线人数统计3 使用 hyperloglog 做统计4 使用 bitmap 统计1 用表统计方式 用数据表统计在线人数,这种方式...
    99+
    2024-04-02
  • 用PHP来统计在线人数的四个方法详解
    本篇文章给大家带来了关于PHP的相关知识,其中主要介绍了怎么实现统计在线人数的问题,可以利用表统计方式、用redis有序集合统计、用hyperloglog做统计等等,下面一起来看一下,希望对大家有帮助。一个业务系统网站每天人数的访问量是多少...
    99+
    2022-06-14
    php
  • Activity 四种启动模式详细介绍
    Activity 四种启动模式详细介绍在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作。在Android中Activity的启动模式决定了Activity的启动运行方式。Andr...
    99+
    2023-05-31
    activity 启动模式 ct
  • Android LaunchMode四种启动模式详细介绍
    Android LaunchMode详解 越是做的时间越长,基础知识就忘的越干净,最近做一个项目中,发现启动的几个Activity居然重叠了,我ri~~,再不回忆一下就要退出A...
    99+
    2022-06-06
    启动 Android
  • Java的24种设计模式详细介绍
    这篇文章主要介绍“Java的24种设计模式详细介绍”,在日常操作中,相信很多人在Java的24种设计模式详细介绍问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java的24种设计模式详细介绍”的疑惑有所帮助!...
    99+
    2023-06-16
  • PHP+REDIS如何统计在线人数
    小编给大家分享一下PHP+REDIS如何统计在线人数,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!在线人数统计业务是我们开发web肯定要设计的业务逻辑,本文就会给...
    99+
    2023-06-14
  • ASP.NET 使用 Dispose 释放资源的四种方法详细介绍
    目录1. 创建一个实现 IDisposable 接口的类2. 使用 “using” 语句处理 IDisposable 对象3. 在请求结束时处理 IDisposable 对象4. 使...
    99+
    2024-04-02
  • ajax数据传输方式详细介绍
    这篇文章主要介绍“ajax数据传输方式详细介绍”,在日常操作中,相信很多人在ajax数据传输方式详细介绍问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”ajax数据传输方式详细...
    99+
    2024-04-02
  • JavaScript闭包以及几种设计模式的详细介绍
    这篇文章主要介绍“JavaScript闭包以及几种设计模式的详细介绍”,在日常操作中,相信很多人在JavaScript闭包以及几种设计模式的详细介绍问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方...
    99+
    2024-04-02
  • java线程池的四种创建方式详细分析
    目录前言1. 线程池2. 创建方式前言 在讲述线程池的前提 先补充一下连接池的定义 连接池是创建和管理一个连接的缓冲池的技术,这些连接准备好被任何需要它们的线程使用 可以看到其连接池...
    99+
    2024-04-02
  • 如何用PHP来统计在线人数
    今天小编给大家分享一下如何用PHP来统计在线人数的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1 用表统计方式用数据表统计在...
    99+
    2023-07-02
  • 详细介绍PHP函数和方法的区别
    随着互联网技术的发展,PHP已经成为了非常流行的开发语言之一。身为一个PHP开发者,了解PHP函数和方法的区别是非常重要的,因为它们在编写代码的时候都是必不可少的。在本文中,我们将详细介绍PHP函数和方法的区别。PHP函数是一段可重复使用的...
    99+
    2023-05-14
    php php函数
  • 详细介绍PHP时间转时间戳的几种方法
    PHP时间转时间戳是一项常用的操作,它可以将指定的时间转化为以秒为单位的时间戳。在PHP项目中,时间戳是一个非常重要的概念,它可以用于处理与时间相关的操作,如记录日志、统计时长等。在本文中,我们将介绍PHP时间转时间戳的几种方法。一、使用d...
    99+
    2023-05-14
  • Java实现统计在线人数功能的方法详解
    目录1. 监听器的简介2. Java监听器的类型(1)ServletContextListener(2)HttpSessionListener(3)ServletRequestLis...
    99+
    2024-04-02
  • 详细介绍在pandas中创建category类型数据的几种方法
    在pandas中创建category类型数据的几种方法之详细攻略  T1、直接创建 category类型数据 可知,在category类型数据中,每一个元素的值要么是预设...
    99+
    2024-04-02
  • Linux下rpm、yum和源码三种安装方式详细介绍
    第1章 源码安装 源码包安装会比RPM包安装慢,是因为RPM的软件包是根据特定系统和平台而指定的,经常一种 程序会提供很多RPM包的格式,用户根据系统情况选择适合的RPM包直接安装,而源码包相当于 通用型,可以是用于多...
    99+
    2022-06-04
    Linux rpm yum 源码 安装 Linux rpm yum 安装 rpm yum 源码 安装
  • win8系统的两种界面更新方法图文详细介绍
    Windows 8系统更新有很多方法,这里主要给大家介绍两种界面更新方法。(很详细的图文介绍) 1.首先介绍正常更新方法,在桌面计算机图标点右键属性或者鼠标移至右上角,打开超级菜单栏选择设置,打开电脑信息,...
    99+
    2022-06-04
    两种 详细介绍 界面
  • Java 列表转换为数组的3种详细方法介绍
    1.介绍 List 接口提供了一种存储有序集合的方法。它是 Collection 的子接口。它是一个有序的对象集合,其中可以存储重复值。由于 List 保留了插入顺序,因此它允许元素的位置访问和插入。...
    99+
    2023-09-22
    java jvm 开发语言
  • Vue路由参数的传递与获取方式详细介绍
    目录前言1. 通过动态路由参数传递2. 通过query字符串传递3. props 隐式传递前言 vue 页面路由切换时传参的方式有如下几种: 动态路由参数 它隐藏字段信息,相对于来说...
    99+
    2024-04-02
  • win7电脑怎么连接wifiwin7计算机连接wifi方式详细介绍
    win7电脑怎么连接wifi是许多应用win7的笔记本客户所碰到的问题,一般情形下win7的笔记本全是适用连接WiFi的,因而可以根据wifi网络立即网上而不用有线连接,但是有的新用户第一次应用win7不清楚如何连接,下边根据win7计算机...
    99+
    2023-07-14
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作