Rumah >pembangunan bahagian belakang >tutorial php >Penjelasan terperinci tentang empat kaedah untuk mengira bilangan orang dalam talian menggunakan PHP

Penjelasan terperinci tentang empat kaedah untuk mengira bilangan orang dalam talian menggunakan PHP

WBOY
WBOYke hadapan
2022-06-08 13:51:386639semak imbas

Artikel ini membawakan anda pengetahuan yang berkaitan tentang PHP terutamanya cara mengira bilangan orang dalam talian Anda boleh menggunakan statistik jadual, statistik set tersusun dan statistik hyperloglog Jom lihatlah ia semoga bermanfaat kepada semua.

Penjelasan terperinci tentang empat kaedah untuk mengira bilangan orang dalam talian menggunakan PHP

Kajian yang disyorkan: "Tutorial Video PHP"

Berapa ramai orang melawat tapak web sistem perniagaan setiap hari dan berapa ramai orang dalam talian Berapa ramai? Kami mesti menempah perniagaan seperti ini semasa pembangunan, dan ia juga dalam skop reka bentuk kami! Kerana laman web yang sedang berjalan menggunakan statistik setiap hari.

Bagaimana untuk mengira bilangan orang dalam talian. Terdapat beberapa penyelesaian Kod menggunakan rangka kerja laravel. Boleh dijadikan rujukan semasa pembangunan.

1 Gunakan statistik jadual

Gunakan jadual data untuk mengira bilangan orang dalam talian Kaedah ini hanya boleh digunakan apabila jumlah konkurensi tidak besar.

Mula-mula kami mencipta jadual baharu: log masuk pengguna

Penjelasan terperinci tentang empat kaedah untuk mengira bilangan orang dalam talian menggunakan PHP

Edit

jadual log masuk pengguna

Simulasikan log masuk pengguna, tiada pengguna wujud Simpan sahaja dalam jadual, dan kemas kini maklumat log masuk jika ia wujud

// 客户端唯一的识别码
$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')
      ]);
}

Di sini kami juga perlu membersihkan pengguna yang tidak melakukan apa-apa jika pengguna tidak melakukan apa-apa dalam masa sejam , kami boleh merekodkannya sebagai pengguna yang tidak sah

Kodnya adalah seperti berikut:

// 客户端唯一的识别码
$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')
      ]);
}

Fungsi yang boleh kami laksanakan:

1) Bilangan orang dalam talian pada masa ini

2) Bilangan orang dalam talian dalam tempoh masa tertentu

3) Pengguna dalam talian terkini

4) Tentukan sama ada pengguna dalam talian

// 可实现功能一:当前总共在线人数
$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 Gunakan koleksi pesanan redis untuk melaksanakan statistik populasi dalam talian

Oleh kerana ia berada dalam ingatan, jadi Ia sangat cekap mengira bilangan orang dalam talian dalam tempoh masa tertentu dan melakukan pelbagai operasi pengagregatan. Tetapi jika terdapat ramai orang dalam talian, ia akan mengambil lebih banyak memori. Perkara lain:

Pengguna tidak sah tidak boleh dialih keluar melalui masa operasi pengguna Hanya pengguna yang log keluar secara manual akan dipadamkan daripada koleksi.

Kodnya adalah seperti berikut:

// 客户端唯一的识别码
$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 Gunakan hyperloglog untuk statistik

Berbeza daripada kaedah set yang dipesan, hyperloglog sangat menjimatkan ruang, tetapi fungsinya implements juga sangat mudah, hanya Ia boleh mengira bilangan orang dalam talian, tetapi tidak boleh melaksanakan sebarang fungsi lain.

Redis HyperLogLog ialah algoritma yang digunakan untuk statistik kardinaliti Kelebihan HyperLogLog ialah apabila bilangan atau isipadu elemen input sangat besar, ruang yang diperlukan untuk mengira kardinaliti sentiasa tetap dan sangat kecil.

Dalam Redis, setiap kunci HyperLogLog hanya berharga 12 KB memori untuk mengira kardinaliti hampir 2^64 elemen berbeza. Ini berbeza dengan koleksi yang menggunakan lebih banyak memori semasa mengira kardinaliti Lebih banyak unsur yang ada, lebih banyak memori digunakan.

Walau bagaimanapun, kerana HyperLogLog hanya akan mengira kardinaliti berdasarkan elemen input dan tidak akan menyimpan elemen input itu sendiri, HyperLogLog tidak boleh mengembalikan elemen individu input seperti koleksi.

// 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;));

Penyelesaian ini hanya boleh mengira jumlah orang dalam talian dalam tempoh masa tertentu, tetapi tidak boleh berbuat apa-apa tentang senarai pengguna dalam talian, tetapi ia menjimatkan memori dan tidak memerlukan banyak data statistik. , kita boleh mempertimbangkan penyelesaian ini.

4 Gunakan statistik bitmap

Bitmap menggunakan bit untuk mewakili nilai atau status yang sepadan dengan elemen, dan kuncinya ialah elemen yang sepadan itu sendiri. Kami tahu bahawa 8 bit boleh membentuk satu Byte, jadi peta bit itu sendiri akan menjimatkan ruang storan dengan banyak.

bitmap biasanya digunakan untuk fungsi seperti daftar masuk pengguna, pengguna aktif, pengguna dalam talian, dll.

Kodnya adalah seperti berikut

// 模拟当前用户
$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;;

bitmap tidak menggunakan banyak ruang memori, tetapi memberikan banyak maklumat statistik penyelesaian ini patut disyorkan.

Pembelajaran yang disyorkan: "Tutorial Video PHP"

Atas ialah kandungan terperinci Penjelasan terperinci tentang empat kaedah untuk mengira bilangan orang dalam talian menggunakan PHP. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:learnku.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam