Stories

Detail Return Return

使用 Curl 和 PHP 壓縮 HTTP 請求 - Stories Detail

image.png

壓縮是一種提升網頁和 Web 應用性能的重要且高效的手段。對於 HTMLCSSJavaScriptSVG 等基於文本的資源,通常在服務器端進行壓縮後傳輸至客户端,再由瀏覽器進行解壓,這一過程能夠顯著降低帶寬消耗和縮短傳輸時間。

這一壓縮與解壓的過程對服務器和瀏覽器來説是透明的:服務器在發送資源前自動完成壓縮,而瀏覽器在渲染前會自動解壓。服務器端的軟件和前端開發人員通常無需直接處理壓縮或解壓的細節。

目前主流的壓縮算法種類較少,瀏覽器和服務器會通過 HTTP 頭信息協商使用哪種壓縮方式。在發起 HTTP 請求時,瀏覽器會通過 Accept-Encoding 頭部聲明其支持的編碼算法;如果服務器支持其中一種或多種算法,便可選擇其中一種對響應進行壓縮,並通過 Content-Encoding 頭部告知客户端所使用的壓縮方式。IANA(互聯網號碼分配局)負責維護已註冊編碼算法列表

image.png

PHP 的 Wikipedia 頁面大小約為 549 KB,使用 Brotli(br) 壓縮後僅為 92 KB。HTML 頁面、JSON 響應、SVG 文件、CSS/JS 文件和其他基於文本的文件壓縮效果良好,而且壓縮/解壓資源所需的計算成本與壓縮節省的網絡傳輸時間相比很小。

雖然瀏覽器默認在獲取資源時使用壓縮,但 PHP 的 HTTP 客户端卻不這麼做。流行的 HTTP 客户端 Curl 支持編碼協商和不透明壓縮請求,但需要啓用。

$ch = curl_init('https://en.wikipedia.org/wiki/PHP');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_exec($ch);

以上是向 Wikipedia 上的 PHP 頁面發出 HTTP 請求的簡化示例。Curl 默認不使用 HTTP 壓縮,這會導致傳輸大小增加、請求時間延長:

curl_getinfo($ch, CURLINFO_TOTAL_TIME); // 0.81 sec
curl_getinfo($ch, CURLINFO_SIZE_DOWNLOAD_T); // 548 KB

CURLINFO_SIZE_DOWNLOAD_T該值顯示 Curl 從遠程服務器下載了 548 KB 的數據。由於 Curl(通過標頭)指示不支持壓縮Accept-Encoding,因此服務器未壓縮響應。

使用該CURLOPT_ACCEPT_ENCODING選項,可以顯式指定Accept-Encoding標頭的值。無需手動解碼響應,因為 Curl 會自動執行。請注意,設置該CURLOPT_ACCEPT_ENCODING選項與手動設置標頭不同Accept-Encoding。如果手動設置,Curl 不會自動解碼響應

CURLOPT_ACCEPT_ENCODING值接受一些不直觀的值類型。

  • CURLOPT_ACCEPT_ENCODING = null:重置值,禁用標題和自動解碼。
  • CURLOPT_ACCEPT_ENCODING = "":Curl 根據支持的算法自動發送適當的標頭,並自動解碼響應。
  • CURLOPT_ACCEPT_ENCODING = "identity":客户端希望服務器不要以任何方式對響應進行編碼。
  • CURLOPT_ACCEPT_ENCODING = "gzip":客户端能夠執行gzip算法。
  • CURLOPT_ACCEPT_ENCODING = "br":客户端能夠使用 Brotlibr算法。

CURLOPT_ACCEPT_ENCODING選項實際上接受任何字符串值,並且如果響應Content-Encoding標頭包含已知的編碼算法,Curl 將嘗試對其進行解碼。

最有用且最合適的值CURLOPT_ACCEPT_ENCODING是空字符串("")。它啓用編碼,但不明確聲明算法。這實際上啓用了 Curl 支持和選擇的所有算法。

 $ch = curl_init('https://en.wikipedia.org/wiki/PHP');
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 curl_setopt($ch, CURLOPT_ACCEPT_ENCODING, '');
 curl_exec($ch);

通過該CURLOPT_ACCEPT_ENCODING=""選項,Curl 現在可以使用適當的Accept-Encoding標頭髮出 HTTP 請求,列出它支持的所有算法。

稍後可以使用函數檢索發送的標題curl_getinfo

$ch = curl_init('https://en.wikipedia.org/wiki/PHP');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_ACCEPT_ENCODING, '');
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_exec($ch);

$headers = curl_getinfo($ch, CURLINFO_HEADER_OUT);
var_dump($headers);
 string(103) "GET /wiki/PHP HTTP/2
 Host: en.wikipedia.org
 accept: */*
 accept-encoding: deflate, gzip, br, zstd

服務器可以選擇使用其支持的壓縮算法之一來壓縮響應。這大大減少了傳輸時間和大小:

curl_getinfo($ch, CURLINFO_TOTAL_TIME); // 0.31 秒
curl_getinfo($ch, CURLINFO_SIZE_DOWNLOAD_T); // 90 KB

Curl 根據編譯步驟中設置的選項選擇它支持的壓縮算法。

gzip在大多數發行版中,PHP Curl 都使用、deflat和(Brotli)進行編譯br。但是,也可以通過在支持下zstd進行編譯,並使用新的頭文件重新編譯 PHP 來添加對 的支持。

user avatar big_cat Avatar aitechshare Avatar tangzhangming Avatar huifeideniao Avatar huobaodejianpan Avatar yansudehai_ty9er Avatar junxiudetuoba Avatar manongsir Avatar _60c4a10050259 Avatar sukaaa Avatar wanglizhi_5dd4059a702d2 Avatar
Favorites 11 users favorite the story!
Favorites

Add a new Comments

Some HTML is okay.