<?php #https://xie.infoq.cn/article/9b0827c018443828d2f0ebedf #https://www.bbsmax.com/A/lk5aQwbZ51/ #https://www.php.cn/php-weizijiaocheng-387074.html #setbit u:sign:1000:202108 17 1 uid:month day 1 /* 127.0.0.1:6379> setbit u:sign:1000:202108 17 1 (integer) 0 127.0.0.1:6379> setbit u:sign:1000:202108 16 1 (integer) 0 127.0.0.1:6379> bitcount u:sign:1000:202108 (integer) 2 127.0.0.1:6379> bitfield u:sign:1000:202108 get u31 0 1) (integer) 24576 127.0.0.1:6379> setbit u:sign:1000:202108 15 1 (integer) 0 127.0.0.1:6379> bitfield u:sign:1000:202108 get u31 0 1) (integer) 57344 127.0.0.1:6379> setbit u:sign:1000:202108 0 1 (integer) 0 127.0.0.1:6379> setbit u:sign:1000:202108 1 1 (integer) 0 127.0.0.1:6379> setbit u:sign:1000:202108 5 1 (integer) 0 127.0.0.1:6379> bitfield u:sign:1000:202108 get u31 0 1) (integer) 1644224512 127.0.0.1:6379> */ #每月签到信息 $days = 31; // bitfield u:sign:1000:202108 get u31 0 $result = 1644224512;//每set一次都需要改变一下这个值 $list = []; // 从低位到高位遍历,0表示未签到;1表示已签到 for ($i = $days; $i > 0; $i--) { // 本月已经循环完直接退出 if ($i < 0) break; // 定义当前的日期是多少 $local_date = date('Y-m') . '-' . $i; // 右移再左移,如果不等于自己说明最低位是 1,表示已签到 $flag = (($result >> 1 << 1) != $result) ? true : false; // 如果已签到,添加标记为1,否则为0 $list[$local_date] = $flag ? 1 : 0; // 然后右移一位重新赋值计算 $result >>= 1; } var_dump($list); // 假设今天18号,获取连续签到日 $days = 18; $signCount = 0; // bitfield u:sign:1000:202108 get u18 0 $value = 200711; for ($i = $days; $i > 0; $i--) { if ($i < 0) break; if (($value >> 1 << 1) == $value) { if ($i != $days){ break; } } else { $signCount++; } $value >>= 1; } var_dump($signCount);
利用redis的bitmap实现签到
阅读82评论02021-08-27 18:04:55
访客评论