Cet article vous apporte des connaissances pertinentes sur PHP. Il présente principalement comment compter le nombre de personnes en ligne. Vous pouvez utiliser les statistiques de table, utiliser les statistiques d'ensemble ordonnées Redis, utiliser l'hyperloglog pour les statistiques, etc., comme suit. , j'espère que cela sera utile à tout le monde.
Étude recommandée : "Tutoriel vidéo PHP"
Combien de personnes visitent un site Web de système d'entreprise chaque jour et combien de personnes sont en ligne ? Il faut réserver ce genre de business lors du développement, et c'est aussi dans notre périmètre de conception ! Parce qu'un site Web en cours d'exécution utilise des statistiques quotidiennement.
Comment compter le nombre de personnes en ligne ? Il existe plusieurs solutions Le code utilise le framework laravel. Peut être utilisé comme référence lors du développement.
Utilisez des tableaux de données pour compter le nombre de personnes en ligne. Cette méthode ne peut être utilisée que lorsque le degré de simultanéité n'est pas important.
Nous créons d'abord une nouvelle table : user_login
Modifier
user_login table
Simuler la connexion de l'utilisateur, stocker l'utilisateur dans la table s'il n'existe pas et mettre à jour les informations de connexion si elles existent
// 客户端唯一的识别码 $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') ]); }
Ceci doit également être nettoyé régulièrement sans aucune opération. Utilisateurs, si l'utilisateur n'effectue aucune opération dans l'heure, nous pouvons l'enregistrer comme un utilisateur invalide
Le code est le suivant :
// 客户端唯一的识别码 $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') ]); }
Fonctions que nous pouvons implémenter :
1 ) Le nombre de personnes en ligne actuellement
2) Le nombre de personnes en ligne sur une certaine période de temps
3) Le dernier utilisateur en ligne
4) Spécifiez si l'utilisateur est en ligne
// 可实现功能一:当前总共在线人数 $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 ? '在线' : '不在线');
Parce qu'il est en mémoire, il est très efficace et peut compter le nombre de personnes en ligne sur une certaine période de temps, peut effectuer diverses opérations d'agrégation. Mais s’il y a beaucoup de monde en ligne, cela prendra plus de mémoire. Un autre point :
Les utilisateurs invalides ne peuvent pas être effacés pendant le temps d'opération de l'utilisateur. Seuls les utilisateurs qui se déconnectent manuellement seront supprimés de la collection.
Le code est le suivant :
// 客户端唯一的识别码 $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 . ' '; }
Différent de la méthode de collecte ordonnée, hyperloglog économise beaucoup d'espace, mais la fonction qu'il implémente est également très simple. Il ne peut compter que le nombre de personnes en ligne. et ne peut implémenter aucune autre fonction.
Redis HyperLogLog est un algorithme utilisé pour les statistiques de cardinalité. L'avantage de HyperLogLog est que lorsque le nombre ou le volume des éléments d'entrée est très grand, l'espace requis pour calculer la cardinalité est toujours fixe et très petit.
Dans Redis, chaque clé HyperLogLog ne coûte que 12 Ko de mémoire pour calculer la cardinalité de près de 2^64 éléments différents. Cela contraste fortement avec une collection qui consomme plus de mémoire lors du calcul de la cardinalité. Plus il y a d'éléments, plus la mémoire est consommée.
Cependant, comme HyperLogLog calculera uniquement la cardinalité en fonction des éléments d'entrée et ne stockera pas les éléments d'entrée eux-mêmes, HyperLogLog ne peut pas renvoyer chaque élément de l'entrée comme une collection.
// 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'));
Cette solution ne peut compter que le nombre total de personnes en ligne sur une certaine période de temps, mais ne peut rien faire sur la liste des utilisateurs en ligne, mais elle économise de la mémoire. S'il n'y a pas beaucoup d'exigences en matière de données statistiques, nous pouvons considérer cela. sorte de plan.
Bitmap utilise un bit pour représenter la valeur ou le statut correspondant à un élément, et la clé est l'élément correspondant lui-même. Nous savons que 8 bits peuvent former un octet, donc le bitmap lui-même permettra d'économiser considérablement de l'espace de stockage.
bitmap est couramment utilisé pour des fonctions telles que l'enregistrement des utilisateurs, les utilisateurs actifs, les utilisateurs en ligne, etc.
Le code est le suivant
// 模拟当前用户 $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 ne consomme pas beaucoup d'espace mémoire, mais fournit de nombreuses informations statistiques. Cette solution mérite d'être recommandée.
Apprentissage recommandé : "Tutoriel vidéo PHP"
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!