Keywords: PHP | file_get_contents | HTTP headers
Abstract: This article explores methods for sending custom HTTP request headers using PHP's file_get_contents() function. By utilizing stream_context_create() to create stream contexts, headers such as Accept-language, Cookie, and User-Agent can be configured. It also addresses potential HTTP protocol version issues in Docker environments, providing solutions and code examples to optimize HTTP request handling.
Introduction
In PHP development, the file_get_contents() function is commonly used to read content from remote URLs, but its default configuration may not support custom HTTP request headers. Based on Q&A data and reference articles, this article provides an in-depth analysis of how to set request headers via stream contexts and discusses potential issues in environments like Docker.
Setting HTTP Headers with stream_context_create()
The file_get_contents() function does not directly support setting HTTP headers, but this can be achieved by creating a stream context with stream_context_create(). Below is an example code demonstrating how to set multiple HTTP headers:
$opts = [
"http" => [
"method" => "GET",
"header" => "Accept-language: en\r\n" .
"Cookie: foo=bar\r\n"
]
];
$context = stream_context_create($opts);
$file = file_get_contents('http://www.example.com/', false, $context);In this code, the header field is defined as a string, with each header separated by \r\n. This allows setting standard headers like HTTP_ACCEPT, HTTP_ACCEPT_LANGUAGE, and HTTP_CONNECTION. For instance, adding a User-Agent header can simulate specific clients:
$options = array(
'http'=>array(
'method'=>"GET",
'header'=>"Accept-language: en\r\n" .
"Cookie: foo=bar\r\n" .
"User-Agent: Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.102011-10-16 20:23:10\r\n"
)
);This approach is flexible and efficient, avoiding the need to modify global settings in php.ini and is suitable for dynamic request scenarios.
HTTP Protocol Issues in Docker Environments
As noted in reference articles, when running PHP applications in Docker containers, file_get_contents() may hang due to HTTP protocol version mismatches. By default, versions before PHP 8 use HTTP/1.0 and send a "Connection: close" header, but Docker might change this to HTTP/1.1. If the server responds with chunked transfer encoding and the client waits for the server to close the connection, it can lead to timeouts.
Solutions include explicitly setting the protocol version or using alternative functions like cURL. For example, adding "protocol_version" => 1.1 in the stream context can enforce HTTP/1.1:
$opts = [
"http" => [
"method" => "GET",
"header" => "Connection: close\r\n",
"protocol_version" => 1.1
]
];This helps prevent connection issues and ensures stable operation in complex environments.
Best Practices and Alternatives
While using file_get_contents() with stream contexts is an effective method for setting HTTP headers, in high-concurrency or complex request scenarios, the cURL extension is recommended. cURL offers richer features, such as handling redirects, SSL verification, and custom timeouts. For example:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.example.com/");
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Accept-language: en',
'Cookie: foo=bar'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);Additionally, always validate stream context configurations and use error-handling mechanisms to catch potential issues, such as network timeouts or invalid URLs.
Conclusion
By leveraging stream_context_create(), developers can flexibly set HTTP request headers in file_get_contents(), enhancing application customizability. In containerized environments like Docker, pay attention to HTTP protocol version compatibility and consider cURL as an alternative. The code examples and analyses in this article, based on actual Q&A data, help readers deeply understand core concepts of PHP HTTP request handling.