我在数据库中索引了很多静态JSON文本内容。其中一些内容大于20K。网页通过Ajax和对PHP文件的调用来请求这些内容,以获取数据库中的数据。
当然,可以动态地对返回的内容进行gzip,但我想知道是否可以获取预gzip的内容并直接从PHP返回。换句话说,我可以预处理gzip条目,并将它们存储在数据库本身中,而不是全文中。
这可能吗?如果是,我如何在PHP中指示返回的内容是gzipped二进制的?我对纯文本使用echo
,但对二进制数据应该使用哪个命令?我不是PHP方面的专家。谢谢
您还将回显gzipped数据。echo只是"将这些字节写入输出缓冲区"。如果需要,可以回声图像。有趣的是,你告诉浏览器如何处理数据。这就是HTTP响应标头的来源。您需要发送一个Content-Encoding标头。但您需要确保客户端能够理解gzip,这样才能正常工作。您还应该知道,有两种不同的压缩算法在使用:DEFLATE和GZIP。
<?php
$data = fetchGzippedDataFromDatabase();
if (stripos($_SERVER["HTTP_ACCEPT_ENCODING"], 'gzip') !== false) {
header('Content-Encoding: gzip');
header('Content-Length: ' . strlen($data));
echo $data;
} else {
// client does not accept gzipped data
echo gzdecode($data);
// or gzinflate() or gzuncompress()
// depending on what you used to compress in the first place
}
您可能需要考虑使用反向代理(nginx、varnish、squid…),并让它们处理输出压缩。
是的,这是可能的。
您需要通过标头函数修改HTTP标头(内容类型、内容长度、传输编码)。
但是要注意,您需要解析客户端提出的已接受的传输编码(deflate、gzip等),并处理所有。如果您将deflate发送到gzip客户端,或者反之亦然,它将无法按预期工作。
另外,请记住,gzip传输编码和gzip文件格式之间有区别。您可能需要找到一个在php中实现这一点的库,或者自己做一些肮脏的工作。
不管怎样,祝你好运!
由于内容是静态的,我建议您完全绕过"从数据库获取"步骤,并尝试一种支持gzip编码响应或缓存gzip版本的缓存机制。
这里有一个链接,指向为Apache做这件事的人。另一个解决方案是Varnish。
Apache Web Server Alternative
首先,如果您使用的是Apache Web Server,则可能需要启用和配置mod_deflate。它将在将内容发送到客户端之前处理内容压缩。
PHP备选方案#1
如果没有,那么您可以使用ob_gzhandler(PHP 4>=4.0.4,PHP 5)来激活gzip输出缓冲区。
if(!ob_start("ob_gzhandler")) ob_start();
echo $json;
PHP备选方案#2
另一种可能性(未测试)可能是将内容缓存在磁盘上,而不是将gzip内容放入数据库,如果这些内容更多地以未压缩格式使用的话。使用gzencode。
$json = array('id' => $id, 'content' => $content);
$file = '/tmp/' . $json['id'] . '.json';
if(!file_exists($file)) {
$gzip = gzencode($json['content']);
file_put_contents($file, $gzip);
} else {
$gzip = file_get_contents($file);
}
header('Content-Encoding: gzip');
header('Content-Length: '.strlen($gzip));
echo $gzip;
这种方式可能只适用于输出gzipped内容,并且可能不适用于所有浏览器。
PHP备选方案#2.5
当浏览器只接受时,从磁盘缓存输出gzip映射的内容。
$json = array('id' => $id, 'content' => $content);
if( strpos($_SERVER["HTTP_ACCEPT_ENCODING"],'gzip') !== false ) {
$file = '/tmp/' . $json['id'] . '.json';
if(!file_exists($file)) {
$gzip = gzencode($json['content']);
file_put_contents($file, $gzip);
} else {
$gzip = file_get_contents($file);
}
header('Content-Encoding: gzip');
header('Content-Length: '.strlen($gzip));
echo $gzip;
} else {
echo $json['content'];
}