php gzuncompress data error问题解决


最近一个项目里使用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
无解,看中文解释 https://segmentfault.com/a/1190000008305573

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*',问题解决。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值