首页后端开发PHPPHP中怎么实现统计在线人数,代码是什么

PHP中怎么实现统计在线人数,代码是什么

时间2024-03-23 08:04:03发布访客分类PHP浏览615
导读:在实际案例的操作过程中,我们可能会遇到“PHP中怎么实现统计在线人数,代码是什么”这样的问题,那么我们该如何处理和解决这样的情况呢?这篇小编就给大家总结了一些方法,具有一定的借鉴价值,希望对大家有所帮助,接下来就让小编带领大家一起了解看看吧...
在实际案例的操作过程中,我们可能会遇到“PHP中怎么实现统计在线人数,代码是什么”这样的问题,那么我们该如何处理和解决这样的情况呢?这篇小编就给大家总结了一些方法,具有一定的借鉴价值,希望对大家有所帮助,接下来就让小编带领大家一起了解看看吧。

 

一个业务系统网站每天人数的访问量是多少,在线人数是多少?这种业务我们在开发中就要预留,也是在我们的设计范围内的咯!因为一个正在运营的网站,每天都会用到统计。

那在线人数是如何统计的呢,这里有几种方案,代码用 laravel 框架。可以作为开发中参考。

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中怎么实现统计在线人数,代码是什么”的相关知识,感谢各位的阅读,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注网络,小编每天都会为大家更新不同的知识。

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!

php

若转载请注明出处: PHP中怎么实现统计在线人数,代码是什么
本文地址: https://pptw.com/jishu/651207.html
MySQL视图能用索引吗,视图究竟是什么 PHP面向对象基础知识有哪些,有哪些要点

游客 回复需填写必要信息