Php 如何将redis位图(二进制字符串)转换为前导为零的二进制数?

Php 如何将redis位图(二进制字符串)转换为前导为零的二进制数?,php,bitmap,redis,bitset,Php,Bitmap,Redis,Bitset,我正在使用redis位图记录一年中的用户操作,如果用户在一年中的第一天登录,我会将键的第一位设置为1。redis值如下所示: 键:user.18.操作(18是用户id) 值:(位图)0001000000000000…(大约365位长) 但是当我试图获取值时,get user.18.action返回“\x10” 在PHP中,如何将这些字符串转换为0001000000000000…对象 事实上,我使用下面的代码来实现它,但是这样行吗?还有更好的解决方案吗 $bitmap = $this->re

我正在使用redis位图记录一年中的用户操作,如果用户在一年中的第一天登录,我会将键的第一位设置为1。redis值如下所示:

键:
user.18.操作
(18是用户id)
值:(位图)0001000000000000…(大约365位长)

但是当我试图获取值时,
get user.18.action
返回
“\x10”

在PHP中,如何将这些字符串转换为
0001000000000000…
对象

事实上,我使用下面的代码来实现它,但是这样行吗?还有更好的解决方案吗

$bitmap = $this->redis->get('user.18.action');
$binstrlen = strlen($bitmap);
$hex = bin2hex($bitmap);
$str = str_baseconvert($hex, 16, 2);
var_dump(str_pad($str, $binstrlen * 8, '0', STR_PAD_LEFT));

function str_baseconvert($str, $frombase=10, $tobase=36) { 
    $str = trim($str); 
    if (intval($frombase) != 10) { 
        $len = strlen($str); 
        $q = 0; 
        for ($i=0; $i<$len; $i++) { 
            $r = base_convert($str[$i], $frombase, 10); 
            $q = bcadd(bcmul($q, $frombase), $r); 
        } 
    } 
    else $q = $str; 

    if (intval($tobase) != 10) { 
        $s = ''; 
        while (bccomp($q, '0', 0) > 0) { 
            $r = intval(bcmod($q, $tobase)); 
            $s = base_convert($r, 10, $tobase) . $s; 
            $q = bcdiv($q, $tobase, 0); 
        } 
    } 
    else $s = $q; 

    return $s; 
}
$bitmap=$this->redis->get('user.18.action');
$binstrlen=strlen($bitmap);
$hex=bin2hex($bitmap);
$str=str_baseconvert($hex,16,2);
var_dump(str_pad($str,$binstrlen*8,'0',str_pad_LEFT));
函数str_baseconvert($str,$frombase=10,$tobase=36){
$str=修剪($str);
如果(intval($frombase)!=10{
$len=strlen($str);
$q=0;
对于($i=0;$i0){
$r=intval(bcmod($q,$tobase));
$s=基本换算($r,10,$tobase)。$s;
$q=bcdiv($q,$tobase,0);
} 
} 
else$s=$q;
返回$s;
}

我想出来了,一切正常。

位图_human func在我头上

 /**
 * @param \Redis $redis
 * @param $key
 * @param $or_login_user
 * @return array
 */
protected function parseUserList(\Redis &$redis, $key)
{
    $bitmap = $this->bitmap_human($redis->get($key));
    $bitmap_length = strlen($bitmap);
    $bitSet = [];

    for ($i = 0; $i < $bitmap_length; $i++) {
        if (1 == $bitmap[$i]) {
            $bitSet[] = $i;
        }
    }

    if(empty($bitSet)){
        return [];
    }

    $login_user = M('user')->cache(600)->field('id,phone,nickname')->where(['id'=>['in',$bitSet]])->select();

    return $login_user;
}
/**
*@param\Redis$Redis
*@param$key
*@param$或\u登录\u用户
*@return数组
*/
受保护的函数parseUserList(\Redis&$Redis,$key)
{
$bitmap=$this->bitmap\u human($redis->get($key));
$bitmap_length=strlen($bitmap);
$bitSet=[];
对于($i=0;$i<$bitmap\u length;$i++){
如果(1==$bitmap[$i]){
$bitSet[]=$i;
}
}
if(空($bitSet)){
返回[];
}
$login_user=M('user')->缓存(600)->字段('id,phone,昵称')->其中(['id'=>['in',$bitSet]])->选择();
返回$login\u用户;
}

所以您需要一个365位长的二进制数据来分配和检索??在redis的控制下,值长度将增长,我所需要做的只是
SETBIT
。需要澄清的是:它总是365位长吗??只有一位将被设置为
1
@missingcat92no,值长度不是固定的,它将随着用户登录的日期而增长。看见
 /**
 * @param \Redis $redis
 * @param $key
 * @param $or_login_user
 * @return array
 */
protected function parseUserList(\Redis &$redis, $key)
{
    $bitmap = $this->bitmap_human($redis->get($key));
    $bitmap_length = strlen($bitmap);
    $bitSet = [];

    for ($i = 0; $i < $bitmap_length; $i++) {
        if (1 == $bitmap[$i]) {
            $bitSet[] = $i;
        }
    }

    if(empty($bitSet)){
        return [];
    }

    $login_user = M('user')->cache(600)->field('id,phone,nickname')->where(['id'=>['in',$bitSet]])->select();

    return $login_user;
}