为什么在我的PHP演示中不能用Go解压gzip数据,但是PHP gzip数据到Go是成功的?我需要post gzip JSON数据从Go到PHP API服务。
测试结果 -> | 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失败
<<p> 去代码/strong>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代码中,你想用
gzdecode
代替gzinflate
。如果用这个,就不需要substr($data, 10)
了。我没有阅读deflate与gzip的关系,但简单的是gzencode
/gzdecode
匹配golanggzip
包和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代码中的所有错误。这段代码看起来只是一个测试,所以我就不赘述了,但是您肯定希望进行适当的错误处理(要么向用户报告问题,要么向函数的调用者报告问题)。