HTTP Response 標頭含 Transfer-Encoding: chunked 時,Body 由多個 Chunk 組成:
Chunked-Body = *chunk
"0" CRLF
footer
CRLF
chunk = chunk-size [ chunk-ext ] CRLF
chunk-data CRLF
chunk-size = hex-no-zero *HEX (十六進位長度,不含前導 0)
chunk-size 與 CRLFchunk-size > 0:讀取指定長度的 chunk-data 及 CRLF,附加至實體內容chunk-size == 0<?php
function decodeChunked($socketFd) {
$body = '';
$chunkSize = (int)hexdec(fgets($socketFd, 4096));
while (!feof($socketFd) && $chunkSize > 0) {
$body .= fread($socketFd, $chunkSize);
fread($socketFd, 2); // 跳過 CRLF
$chunkSize = (int)hexdec(fgets($socketFd, 4096));
}
// 讀取 footer(略)
return $body;
}
?>
hexdec() 將十六進位長度轉十進位fgets() 逐行讀取 size 行fread($fd, 2) 精確跳過 \r\nchunkSize == 0 或 EOF現代替代方案:PHP 5.4+ 內建 http_response_code()、stream_context_create() 等高階函式,或使用 Guzzle、Symfony HttpClient 等成熟庫。