ホームページ  >  記事  >  バックエンド開発  >  PHPを使ってオンライン人数をカウントする4つの方法を詳しく解説

PHPを使ってオンライン人数をカウントする4つの方法を詳しく解説

WBOY
WBOY転載
2022-06-08 13:51:386615ブラウズ

この記事は、PHP に関する関連知識を提供します。オンラインの人数をカウントする方法を主に紹介します。テーブル統計、Redis 順序セット統計、ハイパーログログを使用できます。統計などを実行します。皆さんの参考になれば幸いです。

PHPを使ってオンライン人数をカウントする4つの方法を詳しく解説

推奨学習: 「PHP ビデオ チュートリアル

業務システム Web サイトに毎日何人がアクセスするか、またその数オンラインは何人ですか?この種のビジネスは開発中に予約する必要があり、それも設計範囲内です。運営中のウェブサイトでは毎日統計が使用されるためです。

オンラインの人数をカウントするにはどうすればよいですか? 解決策はいくつかありますが、コードでは laravel フレームワークを使用しています。開発時の参考としてご利用いただけます。

1 テーブル統計メソッドを使用する

データ テーブルを使用してオンラインの人数をカウントします。この方法は、同時実行量が大きくない場合にのみ使用できます。

まず、新しいテーブルを作成します: user_login

PHPを使ってオンライン人数をカウントする4つの方法を詳しく解説

Edit

user_login table

ユーザー ログインをシミュレートします (ユーザーなし)。テーブルに保存し、存在する場合はログイン情報を更新するだけです

// 客户端唯一的识别码
$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 時間以内に操作がない場合は、記録できます。無効なユーザーとして実行します

コードは次のとおりです:

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

2 Redis 順序付きコレクションを使用してオンライン人口を実装します統計

メモリ上にあるため非常に効率的でカウント可能一定期間内のオンライン人数に対して様々な集計操作が可能です。ただし、オンラインに接続している人が多い場合は、より多くのメモリを消費します。もう 1 つのポイント:

無効なユーザーは、ユーザー操作時間を通じてクリアすることはできません。手動でログアウトしたユーザーのみがコレクションから削除されます。

コードは次のとおりです:

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

3 統計には hyperloglog を使用します

順序付けされた収集方法とは異なり、hyperloglog はスペースを大幅に節約しますが、実装される関数も同様です。非常にシンプルでカウントすることしかできず、オンラインの人数だけでは他の機能は実現できません。

Redis HyperLogLog はカーディナリティ統計に使用されるアルゴリズムです。HyperLogLog の利点は、入力要素の数または量が非常に大きい場合でも、カーディナリティの計算に必要なスペースが常に固定され、非常に小さいことです。 。

Redis では、ほぼ 2^64 の異なる要素のカーディナリティを計算するために、各 HyperLogLog キーに必要なメモリは 12 KB のみです。これは、カーディナリティの計算時により多くのメモリを消費するコレクションとは対照的で、要素が多いほど、より多くのメモリが消費されます。

ただし、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(&#39;002|online_users_day_&#39;.$i, [$user_id]);
    }
}
$count = 0;
for ($i=0; $i < 3; $i++) { 
    $count += $redis->pfcount(&#39;002|online_users_day_&#39;.$i);
    print_r($redis->pfcount(&#39;002|online_users_day_&#39;.$i). "\n");
}
var_dump($count);
//note  3 days total online num
var_dump($redis->pfmerge(&#39;002|online_users_day_both_3&#39;, [&#39;002|online_users_day_0&#39;, &#39;002|online_users_day_1&#39;, &#39;002|online_users_day_2&#39;]));
var_dump($redis->pfcount(&#39;002|online_users_day_both_3&#39;));

このソリューションは、一定期間のオンライン ユーザーの総数をカウントすることしかできませんが、オンライン ユーザーのリストについては何もできませんが、メモリは節約されます。統計データの要件がそれほど多くない場合、このオプションを検討してみてはいかがでしょうか。

4 ビットマップ統計を使用する

ビットマップは、ビットを使用して要素に対応する値またはステータスを表し、キーは対応する要素自体です。 8 ビットでバイトを形成できることがわかっているため、ビットマップ自体によりストレージ スペースが大幅に節約されます。

ビットマップは、ユーザーのチェックイン、アクティブ ユーザー、オンライン ユーザーなどの機能によく使用されます。

コードは次のとおりです

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

ビットマップはメモリ領域をあまり消費しませんが、多くの統計情報を提供します。このソリューションは推奨する価値があります。

推奨学習: 「PHP ビデオ チュートリアル

以上がPHPを使ってオンライン人数をカウントする4つの方法を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はlearnku.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。