PHP Conference Japan 2024

Zlib 函式

目錄

新增註解

使用者貢獻的註解 19 則註解

anzenews at volja dot net
18 年前
php at seven dot net dot nz
您是否使用了會輸出內容的 register_shutdown_function()?如果是,則部分輸出未經編碼,而 IE6 對此相當嚴格。在我的情況下,它會重新載入頁面,有時會顯示空白頁面。因此,IE6 確實收到了無效的串流,錯誤並非虛假,只是描述不夠充分。

jpleveille at webgraphe dot com
在 PHP 4.4.2 中,register_shutdown_function() 的確會輸出您想要的任何內容,但它不會與文件的其餘部分一起編碼。這更糟糕,因為您會遇到難以/不可能追蹤的錯誤。
zigazou at free dot fr
20 年前
如果您在 php.ini 檔案中使用 "zlib.output_compression = On" 並啟用輸出緩衝 (ob_start),請勿輸出此標頭
header('Content-Length: '.ob_get_length());

這是因為 ob_get_length() 會傳回未壓縮的大小,而 zlib 會壓縮輸出。因此,您的瀏覽器會因為等待永遠不會出現的額外資料而混淆。
gem at rellim dot com
20 年前
立即將此添加到您的 Apache 設定檔中

php_flag zlib.output_compression On
php_value zlib.output_compression_level 5

我剛試過這個,在一些成熟的 php 頁面上達到了 10 倍和 15 倍的速度提升
一些我一直在努力提升 5% 速度的頁面。我在關鍵頁面上使用 microtime() 來幫助我追蹤頁面速度,這也證實了速度的提升。php 頁面在開始和結束時都加上時間戳記,然後記錄頁面持續時間。因此不包含任何 IP 傳輸效應。使用者可以明顯感受到差異。
測試系統是 PHP 4.3.6、Apache 2.0.49,運行於 Linux 2.4。

一如往常,結果可能有所不同。
As always YMMV. (結果可能依情況而異)
mlevy at rgj dot com
21 年前
如果您開啟了 zlib.output_compression_level,請注意,您不應該在腳本中嘗試使用 flush() 函式輸出。PHP 會添加 gzip 標頭,但會以未壓縮的方式發送輸出,這會對 Mozilla 造成嚴重影響。不過,IE 似乎可以處理它。
Brian
17 年前
如果您的腳本啟動時(在 php.ini 中或通過 Apache 指令)將 zlib.output_compression 設定為開啟,然後在運行時使用 ini_set() 在產生輸出之前將其禁用,您的輸出仍然會被緩衝!即使您調用了 ob_implicit_flush() 也是如此。

如果您想要非緩衝輸出,則必須在腳本啟動之前禁用 zlib.output_compression(當然,如果您同時安裝了 mod_gzip,也要禁用它)。

此行為在以下伺服器上出現:Apache/1.3.33 (Debian GNU/Linux) mod_gzip/1.3.26.1a PHP/4.3.10-18
admin_at_commandline_dot_ch
20 年前
我的 gzip 函式。

此函式一次只讀取、壓縮和寫入小塊資料,這樣您就可以壓縮大檔案而不會出現記憶體問題…

<?php
function gzip($src, $level = 5, $dst = false){
if(
$dst == false){
$dst = $src.".gz";
}
if(
file_exists($src)){
$filesize = filesize($src);
$src_handle = fopen($src, "r");
if(!
file_exists($dst)){
$dst_handle = gzopen($dst, "w$level");
while(!
feof($src_handle)){
$chunk = fread($src_handle, 2048);
gzwrite($dst_handle, $chunk);
}
fclose($src_handle);
gzclose($dst_handle);
return
true;
} else {
error_log("$dst 檔案已存在");
}
} else {
error_log("$src 檔案不存在");
}
return
false;
}
?>
Robin Skoglund
16 年前
ini_set('zlib.output_compression', 'On') 無效

說明文件指出 zlib.output_compression 是 PHP_INI_ALL 可修改的,但至少在我的情況下,這並非事實。當在運行時使用 ini_set('zlib.output_compression', 'On') 時,phpinfo() 顯示 zlib.output_compression 已啟用,但實際上並沒有進行壓縮。

因為我不想在 php.ini 中對所有網站啟用 zlib.output_compression,我的解決方案是在 Apache 設定檔(.htaccess 應該也適用)中用以下這行來啟用它:
php_flag zlib.output_compression on

我花了幾個小時才搞清楚,希望這能幫助到其他人。

順帶一提,我使用的是 Apache/2.2.4 (Ubuntu) PHP/5.2.3-1ubuntu6.3。
Bob
19 年前
與文件所述相反,從 php 4.3.11 開始,我無法透過 ini_set() 讓 zlib.output_compression 生效(即使我把它放在檔案的最開頭,在任何輸出發送之前)。雖然它確實被設定為 true,但實際上卻沒有任何作用。這意味著,如果您不透過 php.ini 或 Apache 設定來設定它,那就行不通了。我不得不改用 ob_start("ob_gzhandler");。
djmaze(AT)dragonflycms(.)org
19 年前
如果您需要壓縮資料並以「Content-disposition: attachment」的方式即時傳送給客戶端,例如因為檔案大小(40MB)的緣故,這裡有一個使用 ob_gzhandler() 的小技巧。

請記住,$str 是要輸出的內容。

當您開始輸出時,請呼叫

<?php
echo ob_gzhandler($str, PHP_OUTPUT_HANDLER_START);
?>

然後要輸出任何其他內容時

<?php
echo ob_gzhandler($str, PHP_OUTPUT_HANDLER_CONT);
?>

以及要關閉輸出時

<?php
echo ob_gzhandler('', PHP_OUTPUT_HANDLER_END);
exit;
?>

僅在 Apache 1.3.33 與 PHP 5.0.4 上測試過
Arne dot Heizmann at csr dot com
18 年前
這裡是 PHP 版本 5.1.4。即使在這個版本(撰寫本文時的最新版本)中,Bob 所說的也是正確的。您無法透過 ini_set() 啟用 zlib.output_compression。您必須使用 php.ini。
spam at wildpeaks dot com
20 年前
為了進行解壓縮,我修改了之前發佈的一個函式(這樣 $string 就不会有很大的大小,如果 gzip 壓縮檔案很大,可能會超出記憶體限制)

function file_ungzip($fromFile, $toFile) {
$zp = @gzopen($fromFile, "r");
$fp = @fopen($toFile, "w");
while(!@gzeof($zp)) {$string = @gzread($zp, 4096); @fwrite($fp, $string, strlen($string));}
@gzclose($zp);
@fclose($fp);
}
monte at ispi dot net
23 年前
處理 gzip 壓縮的另一種方法是讓 Apache 的 mod_gzip 模組來處理。這似乎與 phpbuilder.com 上的教學相矛盾,該教學說它不會壓縮 php(或任何動態)輸出,但從 1.3.17.1a 版本開始,mod_gzip 對我來說效果很好。

以下是一個 httpd.conf 設定範例

<IfModule mod_gzip.c>
mod_gzip_on Yes
mod_gzip_dechunk Yes
mod_gzip_minimum_file_size 300
mod_gzip_maximum_file_size 0
mod_gzip_maximum_inmem_size 100000
mod_gzip_keep_workfiles No
mod_gzip_temp_dir /tmp
mod_gzip_item_include file \.html$
mod_gzip_item_include file \.jsp$
mod_gzip_item_include file \.php$
mod_gzip_item_include file \.pl$
mod_gzip_item_include mime ^text/.*
mod_gzip_item_include mime ^application/x-httpd-php
mod_gzip_item_include mime ^httpd/unix-directory$
mod_gzip_item_include handler ^perl-script$
mod_gzip_item_include handler ^server-status$
mod_gzip_item_include handler ^server-info$
mod_gzip_item_exclude mime ^image/.*
</IfModule>

這將會自動壓縮所有副檔名為 .php 或 MIME 類型為 x-httpd-php 的檔案輸出。請確定 dechunk 設定為 Yes(啟用)。
jpleveille at webgraphe dot com
19 年前
如果使用了 zlib.output_compression,register_shutdown_function() (https://php.dev.org.tw/register_shutdown_function) 將不會輸出任何東西。

關閉所有已開啟的輸出緩衝區後,才會呼叫關閉函式,因此,例如,如果啟用了 zlib.output_compression,它的輸出將不會被壓縮。
thivierr at telus dot net
21 年前
我發現讀取 gzip 檔案最簡單的方法如下:

echo file_get_contents("compress.zlib:///myphp/test.txt.gz");

要建立 gzip 檔案:
file_put_contents("compress.zlib:///myphp/test.txt.gz","Put this in the file\r\n");

關於這點需要注意的事項:
- 最佳使用的前綴是 "compress.zlib",而不是 "zlib"
- 如果您想指定從根路徑開始的路徑,實際上會以三個斜線結尾。上述路徑對應於 Unix 上的 "/myphp/test.txt" 和 Windows 上的 "c:\myphp\test.txt"(如果 C: 是目前的磁碟機)。我只在 Windows 上測試過。
- 壓縮和解壓縮都使用相同的前綴 "compress.zlib://"(加上一個斜線以取得根目錄)。
- 我使用的是 5.0 版本,所以我不能 100% 確定哪些行為是從哪個版本開始的。
ghassler at speakeasy dot net
19 年前
我針對一個 22k 的頁面測試了所有壓縮級別,以下是我的測試結果(以位元組為單位)

關閉 = 22549
1 = 4297
2 = 4279
3 = 4264
4 = 4117
5 = 4097
6 = 4063
7 = 4011
8 = 3998
9 = 3996

看起來 zlib.output_compression_level 的最佳選擇是 1 或 5。預設值 6 可能也可以。不過,我不確定它們之間的 CPU 使用率差異。
php at seven dot net dot nz
18 年前
zlib.output_compression 在 IE 6 中造成了一些問題,有時頁面無法顯示。這可能很難追蹤,而且 PHP 並不打算修復它,所以希望如果發生這種情況,您可以在搜尋中找到這則注意事項。

http://bugs.php.net/bug.php?id=38026
chris at mad-teaparty dot com
21 年前
不錯的函式。我用另一種方式實現了它

function uncompress($srcName, $dstName) {
$zp = gzopen($srcName, "r");
while(!gzeof($zp))
$string .= gzread($zp, 4096);
gzclose($zp);

$fp = fopen($dstName, "w");
fwrite($fp, $string, strlen($string));
fclose($fp);
}

uncompress("./myfile.txt.gz", "./myfile.txt");

更簡潔的方法是

function uncompress($srcName, $dstName) {
$string = implode("", gzfile($srcName));
$fp = fopen($dstName, "w");
fwrite($fp, $string, strlen($string));
fclose($fp);
}
ec10 at gmx dot net
20 年前
/**
* @return bool
* @param string $in
* @param string $out
* @param string $param = "1"
* @desc 使用 zlib-extension 壓縮檔案
*/
function gzip ($in, $out, $param="1")
{
if (!file_exists ($in) || !is_readable ($in))
return false;
if ((!file_exists ($out) && !is_writable (dirname ($out)) || (file_exists($out) && !is_writable($out)) ))
return false;

$in_file = fopen ($in, "rb");
if (!$out_file = gzopen ($out, "wb".$param)) {
return false;
}

while (!feof ($in_file)) {
$buffer = fgets ($in_file, 4096);
gzwrite($out_file, $buffer, 4096);
}

fclose($in_file);
gzclose($out_file);

return true;
}

/**
* @return bool
* @param string $in
* @param string $out
* @desc 使用 zlib-extension 解壓縮檔案
*/
function gunzip($in, $out)
{
if (!file_exists ($in) || !is_readable ($in))
return false;
if ((!file_exists ($out) && !is_writable (dirname ($out)) || (file_exists($out) && !is_writable($out)) ))
return false;

$in_file = gzopen($in, "rb");
$out_file = fopen($out, "wb");

while (!gzeof($in_file)) {
$buffer = gzread($in_file, 4096);
fwrite($out_file, $buffer, 4096);
}

gzclose($in_file);
fclose($out_file);

return true;
}
xorinox at tiscali dot ch
20 年前
看看這個擴充版本 :)

<?php

function compress( $srcFileName, $dstFileName )
{
// 取得檔案內容
$fp = fopen( $srcFileName, "r" );
$data = fread ( $fp, filesize( $srcFileName ) );
fclose( $fp );

// 寫入壓縮檔案
$zp = gzopen( $dstFileName, "w9" );
gzwrite( $zp, $data );
gzclose( $zp );
}

function
uncompress( $srcFileName, $dstFileName, $fileSize )
{
// 取得壓縮檔的內容
$zp = gzopen( $srcFileName, "r" );
$data = fread ( $zp, $fileSize );
gzclose( $zp );

// 寫入解壓縮檔案
$fp = fopen( $dstFileName, "w" );
fwrite( $fp, $data );
fclose( $fp );
}

compress( "tmp/supportkonzept.rtf", "tmp/_supportkonzept.rtf.gz" );
uncompress( "tmp/_supportkonzept.rtf.gz", "tmp/_supportkonzept.rtf", filesize( "tmp/supportkonzept.rtf" ) );

?>
To Top