您的当前位置:首页正文

php gzuncompress data error问题解决

2024-11-05 来源:个人技术集锦


最近一个项目里使用mysql数据库,维护单位要求字段平均长度必须小于1k,由于存的东西太多,有的达到了14k,所以必须要压缩

开始想的是对内容gzcompress后base64,但这会增加1/3的数据量,考虑到维护单位的变态要求,考虑对内容gzcompress后转成二进制流后直接存成varbinary,这样保存数据就不用考虑编码的问题了。

php转成二进制流使用的就是pack和unpack,使用如下:

    /**
     * 将字符串压缩并转成二进制流
     * @param $string
     * @return string
     */
    public static function gzCompressAndToBinary($string) {
        $cmpr = gzcompress($string);
        return pack('A*', $cmpr);
    }

    /**
     * 将二进制流解压成字符串
     * 与gzCompressAndToBinary操作相反
     * @param $bytes
     * @return mixed
     */
    public static function gzUncompressFromBinary($bytes) {
        $unpacks = unpack('A*', $bytes);
        $gzcomp = '';
        foreach ($unpacks as $k => $v) {
            if (!empty($v)) {
                $gzcomp = $v;
                break; // 测试发现值对应的索引是1,而不是0
            }
        }

        return gzuncompress($gzcomp);
    }

但后来发现gzuncompress会报错“gzuncompress(): data error”

在网上找了各种资料都没有正解,其中有一个人问了存在myISAM模式下没有问题,但保存在innodb模式下会出现解压失败的情况

没有仔细去研究myISAM和innodb的区别,但可以推测是在数据保存过程或数据取出过程中发生了微妙的变化,所以怀疑是在二进制转换时发生的变化,因为压缩和解压缩没有参数影响结果,而pack和unpack时有一个格式字符

查询php说明

pack() format characters
Code Description
aNUL-padded string
ASPACE-padded string
无解,看中文解释

Code Description
a 以NUL字节填充字符串空白
A 以SPACE(空格)填充字符串

$string = pack('a6', 'china');
var_dump($string); //输出结果: string(6) "china",最后一个字节是不可见的NUL
echo ord($string[5]); //输出结果: 0(ASCII码中0对应的就是nul)

//A同理
$string = pack('A6', 'china');
var_dump($string); //输出结果: string(6) "china ",最后一个字节是空格
echo ord($string[5]); //输出结果: 32(ASCII码中32对应的就是空格)
尝试一下使用unpack('a*', $string);来解二进制流,发现可以解之前不能解出来的信息

然后把生成和解二进制流的format都换成'a*',问题解决。

显示全文