小编典典

PHP无法通过Golang解压缩gzip数据

go

为什么在我的PHP演示中无法通过Go解压缩gzip数据,但是成功将PHP gzip数据解压到Go?我需要从Go to PHP API服务发布gzip
JSON数据。

测试结果

 -> |  php   |  go 
---------------------
php |  ok    |  ok
go  |  fail  |  ok

PHP代码

class GzipDemo
{
    public function gzen($data, $file){
       $json_data = json_encode($data);
       $gz_data = gzencode($json_data,9);
       file_put_contents($file,$gz_data);
    }

    public function gzdn($file){
       $data = file_get_contents($file);
        $unpacked = gzdecode($data);
        if ($unpacked === FALSE)
        {
            print("failed:".$file."\n");
        }else{
             print($file. " result Data :".$unpacked ."\n");
        }
    }
}

$demo = new GzipDemo();
$file="phpgzip.txt";
$demo->gzen("data",$file);
$demo->gzdn($file);
$demo->gzdn("gogzip.txt");

结果是:PHP到PHP可以。转到PHP失败。

去代码

package main

import (
    "bytes"
    "compress/gzip"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "os"
)

func main() {
    gzen("data", "gogzip.txt")
    gden("gogzip.txt")
    gden("phpgzip.txt")
}
func gzen(data string, file string) {
    b, _ := json.Marshal(data)
    buffer := new(bytes.Buffer)
    w, _ := gzip.NewWriterLevel(buffer, gzip.BestCompression)
    defer w.Close()
    w.Write(b)
    w.Flush()
    ioutil.WriteFile(file, buffer.Bytes(), os.ModePerm)
}
func gden(file string) {
    b, _ := ioutil.ReadFile(file)
    buffer := new(bytes.Buffer)
    buffer.Write(b)
    r, _ := gzip.NewReader(buffer)
    defer r.close()
    data, _ := ioutil.ReadAll(r)
    fmt.Println(file, " result Data:", string(data))
}

结果是:转到好的。PHP可以了。


阅读 353

收藏
2020-07-02

共1个答案

小编典典

它适用于以下更改:

  • 在您的PHP代码中,您想使用gzdecode而不是gzinflatesubstr($data, 10)如果您使用它,则不需要这些东西。我没有读过deflate与gzip的关系,但简单之处在于gzencode/ gzdecode匹配golang gzip软件包的功能以及gz*GNU命令行工具系列的功能。
  • 在您的Go代码中,移动gzip.Writer.Close()调用以在从中读取之前完成buffer。如您在这里看到的:http : //golang.org/src/compress/gzip/gzip.go?s=6230 : 6260#L240还有一些其他内容在关闭时会写入基础流,因此在您的示例中以上您所写的内容是不完整的。(该defer语句导致Close()在包含函数退出后运行。)很可能Go gzip解码无论如何都会设法解码,而PHP实现却无法解码-在任何情况下,您都应正确关闭流到内存缓冲区中以确保它是在将其写到文件之前完成。

强制性注释:您将忽略Go代码中的所有错误。这段代码看起来只是一个测试,所以我不会太在意这一点,但是您绝对希望进行适当的错误处理(将问题报告给用户或函数的调用者)。

2020-07-02