欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

PHP四種統(tǒng)計(jì)在線人數(shù)方式詳細(xì)介紹

 更新時(shí)間:2022年09月20日 15:35:12   作者:PHP柚子  
這篇文章主要介紹了用PHP來統(tǒng)計(jì)在線人數(shù)的四個(gè)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧

1 用表統(tǒng)計(jì)方式

用數(shù)據(jù)表統(tǒng)計(jì)在線人數(shù),這種方式只能用在并發(fā)量不大的情況下。

首先我們先新建表:user_login

編輯

user_login 表

模擬用戶登錄,不存在用戶就存入表,存在的則更新登錄信息

// 客戶端唯一的識別碼
$client_id = session()->getId();
//用戶是否已存在
$user = DB::table('user_login')
    ->where('token', $client_id)
    ->first();
//不存在則插入數(shù)據(jù)
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')
      ]);
}

這里還需要定期清理無任何操作的用戶,假如用戶一個(gè)小時(shí)內(nèi)無任何操作,我們可以記為無效用戶

代碼如下:

// 客戶端唯一的識別碼
$client_id = session()->getId();
//用戶是否已存在
$user = DB::table('user_login')
    ->where('token', $client_id)
    ->first();
//不存在則插入數(shù)據(jù)
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')
      ]);
}

我們可以實(shí)現(xiàn)的功能:

1)當(dāng)前在線人數(shù)

2)某時(shí)間段內(nèi)在線人數(shù)

3)最新上線的用戶

4)指定用戶是否在線

// 可實(shí)現(xiàn)功能一:當(dāng)前總共在線人數(shù)
$c = DB::table('user_login')->count();
echo '當(dāng)前在線人數(shù):' . $c . '<br />';
// 可實(shí)現(xiàn)功能二:某時(shí)間段內(nèi)在線人數(shù)
$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 . '在線人數(shù):' . $c . '<br />';
// 可實(shí)現(xiàn)功能三:最新上線的用戶
$newest = DB::table('user_login')
    ->orderBy('create_time', 'DESC')
    ->limit(10)
    ->get();
echo '最新上線的用戶有:';
foreach ($newest as $value) {
    echo $value->username . ' ';
}
echo '<br />';
// 可實(shí)現(xiàn)功能四:指定用戶是否在線
$username = 'user_1111';
$online = DB::table('user_login')
    ->where('username', $username)
    ->exists();
echo $username . ($online ? '在線' : '不在線');

2 使用 redis 有序集合實(shí)現(xiàn)在線人數(shù)統(tǒng)計(jì)

因?yàn)槭莾?nèi)存中,所以效率很高,可以統(tǒng)計(jì)某個(gè)時(shí)間段內(nèi)的在線人數(shù),可以做各種聚合操作。但是如果在線人數(shù)比較多的情況下,會比較占用內(nèi)存。還有一點(diǎn):

無法通過用戶操作時(shí)間清除掉無效用戶,只有手動(dòng)登出的用戶才會從集合中刪除。

代碼如下:

// 客戶端唯一的識別碼
$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)) {    // 不在線,加入當(dāng)前客戶端
    Redis::zAdd($key, time(), $client_id);
}
// 可實(shí)現(xiàn)功能一:當(dāng)前總共在線人數(shù)
$c = Redis::zCard($key);
echo '當(dāng)前在線人數(shù):' . $c . '<br />';
// 可實(shí)現(xiàn)功能二:某時(shí)間段內(nèi)在線人數(shù)
$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 . '在線人數(shù):' . $c . '<br />';
// 可實(shí)現(xiàn)功能三:最新上線的用戶,時(shí)間從小到大排序
$newest = Redis::zRangeByScore($key, '-inf', '+inf', ['limit' => [0, 50]]);
echo '最新上線的用戶有:';
foreach ($newest as $value) {
    echo $value . ' ';
}
echo '<br />';
// 可實(shí)現(xiàn)功能四:指定用戶是否在線
$username = $client_id;
$online = Redis::zScore($key, $client_id);;
echo $username . ($online ? '在線' : '不在線') . '<br />';
// 可實(shí)現(xiàn)功能五:昨天和今天都上線的客戶
$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 做統(tǒng)計(jì)

跟有序集合方式不同,hyperloglog 十分節(jié)約空間,但是實(shí)現(xiàn)的功能也非常單一,只能統(tǒng)計(jì)在線人數(shù),不能實(shí)現(xiàn)其余的任何功能。

Redis HyperLogLog 是用來做基數(shù)統(tǒng)計(jì)的算法,HyperLogLog 的優(yōu)點(diǎn)是,在輸入元素的數(shù)量或者體積非常非常大時(shí),計(jì)算基數(shù)所需的空間總是固定 的、并且是很小的。

在 Redis 里面,每個(gè) HyperLogLog 鍵只需要花費(fèi) 12 KB 內(nèi)存,就可以計(jì)算接近 2^64 個(gè)不同元素的基 數(shù)。這和計(jì)算基數(shù)時(shí),元素越多耗費(fèi)內(nèi)存就越多的集合形成鮮明對比。

但是,因?yàn)?HyperLogLog 只會根據(jù)輸入元素來計(jì)算基數(shù),而不會儲存輸入元素本身,所以 HyperLogLog 不能像集合那樣,返回輸入的各個(gè)元素。

// note HyperLogLog 只需要知道在線總?cè)藬?shù)
for ($i=0; $i < 6; $i++) {
    $online_user_num = mt_rand(10000000, 99999999);     //模擬在線人數(shù)
    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'));

這種方案僅僅只能統(tǒng)計(jì)出某個(gè)時(shí)間段在線人數(shù)的總量, 對在線用戶的名單卻無能為力,但是卻挺節(jié)省內(nèi)存的,對統(tǒng)計(jì)數(shù)據(jù)要求不多情況下 ,我們便可以考慮這種方案

4 使用 bitmap 統(tǒng)計(jì)

bitmap 就是通過一個(gè) bit 位來表示某個(gè)元素對應(yīng)的值或者狀態(tài),其中的 key 就是對應(yīng)元素本身。我們知道 8 個(gè) bit 可以組成一個(gè) Byte,所以 bitmap 本身會極大的節(jié)省儲存空間。

bitmap 常用來做比如用戶簽到、活躍用戶、在線用戶等功能。

代碼如下

// 模擬當(dāng)前用戶
$uid = request('uid');
$key = 'online_bitmap_' . date('Ymd');
// 設(shè)置當(dāng)前用戶在線
Redis::setBit($key, $uid, 1);
// 可實(shí)現(xiàn)功能1:在線人數(shù)
$c = Redis::bitCount($key);
echo '在線人數(shù):' . $c . '<br />';
// 可實(shí)現(xiàn)功能2:指定用戶是否在線
$online = Redis::getBit($key, $uid);
echo $uid . ($online ? '在線' : '不在線') . '<br />';
// 可實(shí)現(xiàn)功能3:昨天和今天均上線的用戶總數(shù)
$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 '昨天和今天都上線的用戶數(shù)量有:' . $c . '<br />';

bitmap 消耗的內(nèi)存空間不多, 統(tǒng)計(jì)的信息卻挺多的,這種方案是值得推薦一下的。

到此這篇關(guān)于PHP四種統(tǒng)計(jì)在線人數(shù)方式詳細(xì)介紹的文章就介紹到這了,更多相關(guān)PHP統(tǒng)計(jì)在線人數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • php 3行代碼的分頁算法(求起始頁和結(jié)束頁)

    php 3行代碼的分頁算法(求起始頁和結(jié)束頁)

    涉及到分頁時(shí), 除非只顯示上一頁/下一頁, 否則需要計(jì)算起始頁和結(jié)束頁. 看過很多代碼都是用大量的if-else來實(shí)現(xiàn), 代碼量大, 又不簡潔. 現(xiàn)在提供一種只需要3行代碼的算法.
    2009-10-10
  • 深入研究PHP中的preg_replace和代碼執(zhí)行

    深入研究PHP中的preg_replace和代碼執(zhí)行

    這篇文章主要給大家介紹了關(guān)于PHP中preg_replace和代碼執(zhí)行的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08
  • 用來給圖片加水印的PHP類

    用來給圖片加水印的PHP類

    不錯(cuò)的一個(gè)php添加水印的類
    2008-04-04
  • PHP類中Static方法效率測試代碼

    PHP類中Static方法效率測試代碼

    因?yàn)橛泻脦讉€(gè)項(xiàng)目等著做,又不是很急,再加上目前成型的那些框架多多少少用著總是有點(diǎn)不太如意,所以決定先自己寫一個(gè)框架,然后再做項(xiàng)目。既然寫框架,自然要經(jīng)常做一些執(zhí)行效率上的測試,今天做了一個(gè)static效率的測試。
    2010-10-10
  • php中文字符串截取多種方法匯總

    php中文字符串截取多種方法匯總

    這篇文章主要為大家詳細(xì)介紹了php中文字符串截取多種方法,具有一定的參考價(jià)值,感興趣的朋友可以參考一下
    2016-10-10
  • 淺談COOKIE和SESSION區(qū)別

    淺談COOKIE和SESSION區(qū)別

    在PHP面試中經(jīng)常碰到請闡述session與cookie的區(qū)別與聯(lián)系,以及如何修改兩者的有效時(shí)間。具體來說cookie機(jī)制采用的是在客戶端保持狀態(tài)的方案,而session機(jī)制采用的是在服務(wù)器端保持狀態(tài)的方案。
    2015-07-07
  • php中Y2K38的漏洞解決方法實(shí)例分析

    php中Y2K38的漏洞解決方法實(shí)例分析

    這篇文章主要介紹了php中Y2K38的漏洞解決方法,以實(shí)例形式對php中Y2K38的漏洞的原理及相應(yīng)的解決方法進(jìn)行了較為深入的分析,需要的朋友可以參考下
    2014-09-09
  • thinkphp5實(shí)用入門進(jìn)階知識點(diǎn)和各種常用功能代碼匯總

    thinkphp5實(shí)用入門進(jìn)階知識點(diǎn)和各種常用功能代碼匯總

    這篇文章主要介紹了thinkphp5實(shí)用入門進(jìn)階知識點(diǎn)和各種常用功能代碼匯總的相關(guān)資料,需要的朋友可以參考下
    2023-03-03
  • 在WordPress中實(shí)現(xiàn)發(fā)送http請求的相關(guān)函數(shù)解析

    在WordPress中實(shí)現(xiàn)發(fā)送http請求的相關(guān)函數(shù)解析

    這篇文章主要介紹了在WordPress中實(shí)現(xiàn)發(fā)送http請求的相關(guān)函數(shù)解析,包括使用WP_Http類中的函數(shù)來發(fā)送post或get請求的方法,需要的朋友可以參考下
    2015-12-12
  • ASP和PHP實(shí)現(xiàn)生成網(wǎng)站快捷方式并下載到桌面的方法

    ASP和PHP實(shí)現(xiàn)生成網(wǎng)站快捷方式并下載到桌面的方法

    這篇文章主要介紹了PHP實(shí)現(xiàn)生成網(wǎng)站快捷方式并下載到桌面的方法,比加入收藏、設(shè)為首頁更給力哦,需要的朋友可以參考下
    2014-05-05

最新評論