Я бы бил на байты, и работал с битами и отдельными символами:
$ar = [0, 2, 3, 7, 8];
$maxValue = max( $ar);
if( $maxValue >= pow(2, 32)) {
return; // больше, чем влезет в один ключ в Redis
}
$maxBytes = ceil( $maxValue / 8);
$bin = str_repeat( chr(0x0), $maxBytes);
foreach($ar AS $bitNumber) {
$byteNumber = floor( $bitNumber / 8); // в каком символе строки этот бит окажется
$addon = 1 << ( 7 - $bitNumber % 8); // каков этот бит в своем байте (Redis слева направо)
$byteChar = substr( $bin, $byteNumber, 1); // получаем этот символ из нашей строки
$byteChar = chr( $addon | ord( $byteChar)); // обновляем символ очередным битом
$bin = substr_replace( $bin, $byteChar, $byteNumber, 1); // вставляем обновленный символ в строку
}
// return $bin; // строка готова для Redis'а.
// проверка
for( $i=0; $i<strlen($bin); $i++) printf( "%08b", ord(substr($bin,$i,1)));
echo PHP_EOL;