HTTP context 选项 — HTTP context 的选项列表
提供给 http:// 和 https:// 传输协议的 context 选项。 transports.
版本 | 说明 |
---|---|
5.3.4 | 添加 follow_location。 |
5.3.0 | 当 protocol_version 设置为 1.1 时支持分块传输解码。 |
5.2.10 | 添加 ignore_errors。 |
5.2.10 | header 现在可以是一个数字索引的 array。 |
5.2.1 | 添加 timeout。 |
5.1.0 | Added HTTPS proxying through HTTP proxies. 添加经由 HTTP 代理的 HTTPS 代理。 |
5.1.0 | 添加 max_redirects。 |
5.1.0 | 添加 protocol_version。 |
示例 #1 获取一个页面并发送 POST 数据
示例 #2 忽略重定向并获取 header 和内容
注意: Underlying socket stream context options
Additional context options may be supported by the underlying transport For http:// streams, refer to context options for the tcp:// transport. For https:// streams, refer to context options for the ssl:// transport.
注意: HTTP status line
When this stream wrapper follows a redirect, the wrapper_data returned by stream_get_meta_data() might not necessarily contain the HTTP status line that actually applies to the content data at index 0.The first request returned a 301 (permanent redirect), so the stream wrapper automatically followed the redirect to get a 200 response (index = 4).array ( 'wrapper_data' => array ( 0 => 'HTTP/1.0 301 Moved Permantenly', 1 => 'Cache-Control: no-cache', 2 => 'Connection: close', 3 => 'Location: http://example.com/foo.jpg', 4 => 'HTTP/1.1 200 OK', ...
[#1] ▲0▼ aschmidt@anamera.net [0%] (2021-02-16 14:51:34)
With the default of 'follow_location' => 1 be certain NEVER include a "Host:" header in the 'header' array. If the host is set to "mydomain.com", and that web site has a (quite common) redirect to "www.mydomain.com", then the initial request to "http://mydomain.com" will get the expected response of: HTTP/1.1 301 Moved Permanently Location: http://www.mydomain.com/ However, the follow-up request does NOT replace the original "host" header with the new "location" value, as one would expect. Consequently each "follow-location" request will again be served by the original host of "http://mydomain.com", and continue the redirect loop until 'max_redirects' has been exhausted. (For details: https://bugs.php.net/bug.php?id=77889)
[#2] ▲14▼ daniel.peder (a) gmail.com [82%] (2017-10-16 18:55:50)
note that both http and https transports require the same context name http // OK example: // this will work as expected // note the url with https but context with http $correct_data = file_get_contents('https://example.com', false, stream_context_create(array('http' => array(...)))); // INVALID example: // this will not work, the context will be ignored // note the url with https also context with https $correct_data = file_get_contents('https://example.com', false, stream_context_create(array('https' => array(...))));
[#3] ▲9▼ daniel.peder@gmail.com [80%] (2017-10-16 18:50:44)
note that for both http and https protocols require the same 'http' context keyword:
<?php
// CORRECT example:
// this will work as expected
// note the url with https but context with http
$correct_data = file_get_contents('https://example.com', false, stream_context_create(array('http' => array(...))));
// INVALID example:
// this will not work, the context will be ignored
// note the url with https also context with https
$correct_data = file_get_contents('https://example.com', false, stream_context_create(array('https' => array(...))));
[#4] ▲1▼ aruntechguy@outlook.com [60%] (2017-09-22 02:50:19)
If you want to use Basic Auth while using get_headers(), use stream_context options below.
I am using HEAD method here, but please feel free to use GET also.
<?php
$targetUrl = 'http or https target url here';
$basicAuth = base64_encode('username:password');
stream_context_set_default(
[
'http' => [
'method' => 'HEAD',
'header' => 'Authorization: Basic ' . $basicAuth
]
]
);
$result = get_headers($targetUrl);
print_r($result);
[#5] ▲1▼ ywarnier@beeznest.org [67%] (2017-08-02 08:39:00)
Note that setting request_fulluri to true will *change* the value of $_SERVER['REQUEST_URI] on the receiving end (from /abc.php to http://domain.com/abc.php).
[#6] ▲4▼ jay [57%] (2015-04-14 01:32:45)
Remember to match content with Content-type:
<?php
$data = array(
'var1' => 'some content',
'var2' => 'doh'
);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/json', // here...
'content' => json_encode($data) // and here.
)
);
. . .
?>
[#7] ▲17▼ nate [73%] (2014-04-17 03:19:36)
Note that if you set the protocol_version option to 1.1 and the server you are requesting from is configured to use keep-alive connections, the function (fopen, file_get_contents, etc.) will "be slow" and take a long time to complete. This is a feature of the HTTP 1.1 protocol you are unlikely to use with stream contexts in PHP.
Simply add a "Connection: close" header to the request to eliminate the keep-alive timeout:
<?php
// php 5.4 : array syntax and header option with array value
$data = file_get_contents('http://www.example.com/', null, stream_context_create([
'http' => [
'protocol_version' => 1.1,
'header' => [
'Connection: close',
],
],
]));
?>
[#8] ▲2▼ chris [54%] (2014-02-06 06:14:06)
I had quite a bit of trouble trying to make a request with fopen through a proxy to a secure url. I kept getting a 400 Bad Request back from the remote host. It was receiving the proxy url as the SNI host. In order to get around this I had to explicity set the SNI host to the domain I was trying to reach. It's apparently the issue outlined in this bug:
https://bugs.php.net/bug.php?id=63519
<?php
$domain = parse_url($file, PHP_URL_HOST);
$proxy_string = "tcp://" . WP_PROXY_HOST . ":" . WP_PROXY_PORT;
$opts = array(
'http' => array( 'proxy' => $proxy_string ),
'ssl' => array( 'SNI_enabled' => true, 'SNI_server_name' => $domain));
$context = stream_context_create($opts);
$handle = fopen( $file, 'r', false, $context );
?>
[#9] ▲7▼ vchampion@gmail.com [62%] (2012-10-23 13:41:30)
If you use the proxy server and encounter an error "fopen(http://example.com): failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request" note that in many situations you need also set the parameter "request_fulluri" to "true" in your stream options. Without this option the php script sends the empty request to the server as "GET / HTTP/0.0" and the proxy server replies to it with the "HTTP 400" error.
For example (working sample):
<?php
P>S> PHP 5.3.17
$stream = stream_context_create(Array("http" => Array("method" => "GET",
"timeout" => 20,
"header" => "User-agent: Myagent",
"proxy" => "tcp://my-proxy.localnet:3128",
'request_fulluri' => True /* without this option we get an HTTP error! */
)));
if ( $fp = fopen("http://example.com", 'r', false, $stream) ) {
print "well done";
}
?>
[#10] ▲11▼ gourav sarkar [68%] (2011-01-18 20:09:38)
watch your case when using methods (POST and GET)...it must be always uppercase. in case of you write it in lower case it wont work.