如何检测file_get_contents返回的内容是否为gzip压缩格式?
Absolutely, you can detect whether the fetched content is gzipped and only decode it when needed. There are two reliable approaches to do this—checking the HTTP response headers, or verifying the "magic bytes" of the content itself. Let's break down both methods, plus a combined solution for maximum reliability.
Method 1: Check HTTP Response Headers
When the server sends gzipped content, it typically includes a Content-Encoding: gzip header in the response. You can retrieve these headers while fetching the content and use them to decide whether to decode.
Here's how to do this with file_get_contents using a stream context:
$vid = 231231; // Create a context to tell the server we accept gzip encoding $context = stream_context_create([ 'http' => [ 'header' => 'Accept-Encoding: gzip' ] ]); // Fetch the content and capture response headers $rawContent = file_get_contents("https://www.thevideositeurl.com/embed/{$vid}/", false, $context); $responseHeaders = $http_response_header; // Auto-set by file_get_contents $isGzipped = false; // Loop through headers to check for gzip encoding foreach ($responseHeaders as $header) { if (stripos($header, 'Content-Encoding: gzip') !== false) { $isGzipped = true; break; } } // Decode only if the content is gzipped $decodedContent = $isGzipped ? gzdecode($rawContent) : $rawContent; echo $decodedContent;
Method 2: Check the Content's Magic Bytes
Gzipped files always start with two specific bytes: 0x1F and 0x8B. This is a foolproof way to detect gzipped content even if the server doesn't set the correct header (which can happen occasionally).
Here's how to implement this:
$vid = 231231; $rawContent = file_get_contents("https://www.thevideositeurl.com/embed/{$vid}/"); $isGzipped = false; // Check if we have at least 2 bytes to verify if (strlen($rawContent) >= 2) { $firstTwoBytes = substr($rawContent, 0, 2); // Check if the first two bytes match the gzip magic numbers $isGzipped = (ord($firstTwoBytes[0]) === 0x1F) && (ord($firstTwoBytes[1]) === 0x8B); } // Decode if needed $decodedContent = $isGzipped ? gzdecode($rawContent) : $rawContent; echo $decodedContent;
Combined Approach (Most Reliable)
For the best results, combine both methods: first check the headers, and if that doesn't give a clear answer, fall back to checking the magic bytes. This covers edge cases where servers might not send the correct header.
Here's a robust example using cURL (which gives more control over headers than file_get_contents):
$vid = 231231; $ch = curl_init("https://www.thevideositeurl.com/embed/{$vid}/"); // Configure cURL options curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_ENCODING, 'gzip'); // Tell server we accept gzip curl_setopt($ch, CURLOPT_HEADER, true); // Include response headers in the output // Execute the request $response = curl_exec($ch); $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE); curl_close($ch); // Split headers and content $headers = substr($response, 0, $headerSize); $rawContent = substr($response, $headerSize); $isGzipped = false; // First check headers if (stripos($headers, 'Content-Encoding: gzip') !== false) { $isGzipped = true; } // Fallback to magic bytes if header check fails elseif (strlen($rawContent) >= 2) { $firstTwoBytes = substr($rawContent, 0, 2); $isGzipped = (ord($firstTwoBytes[0]) === 0x1F) && (ord($firstTwoBytes[1]) === 0x8B); } // Decode only when necessary $decodedContent = $isGzipped ? gzdecode($rawContent) : $rawContent; echo $decodedContent;
Notes:
gzdecode()requires PHP 5.4 or later, which is widely supported.- Always include the
Accept-Encoding: gzipheader in your request—this tells the server you're willing to accept compressed content, which can speed up requests. - Using cURL is often more reliable than
file_get_contentsfor handling headers and edge cases, especially if you need to add more request parameters later.
内容的提问来源于stack exchange,提问作者bpy

