Опции контекста HTTP
Опции контекста HTTP — Список опций контекста HTTP
Описание
Опции контекста для транспортных протоколов http:// и https://.
Список изменений
Версия | Описание |
---|---|
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 | Добавлено проксирование протокола HTTPS через HTTP-прокси. |
5.1.0 |
Добавлен параметр max_redirects .
|
5.1.0 |
Добавлен параметр protocol_version .
|
Примеры
Пример #1 Извлечь страницу и отправить данные методом POST
<?php
$postdata = http_build_query(
array(
'var1' => 'некоторое содержимое',
'var2' => 'doh'
)
);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
)
);
$context = stream_context_create($opts);
$result = file_get_contents('http://example.com/submit.php', false, $context);
?>
Пример #2 Игнорировать переадресации, но извлечь заголовки и содержимое
<?php
$url = "http://www.example.org/header.php";
$opts = array('http' =>
array(
'method' => 'GET',
'max_redirects' => '0',
'ignore_errors' => '1'
)
);
$context = stream_context_create($opts);
$stream = fopen($url, 'r', false, $context);
// информация о заголовках, а также
// мета-данные о потоке
var_dump(stream_get_meta_data($stream));
// актуальная информация по ссылке $url
var_dump(stream_get_contents($stream));
fclose($stream);
?>
Примечания
Замечание: Опции контекста низлежащего потока в сокете
Дополнительные опции контекста могут поддерживаться низлежащим транспортным протоколом. Для потоков http://, это относится к опциям контекста для транспортного протокола tcp://. Для потоков https://, это относится к опциям контекста для транспортного протокола ssl://.
Замечание: Строка статуса HTTP
Когда эта обертка потока следует по переадресации, wrapper_data, возвращаемый функцией stream_get_meta_data(), необязательно содержит строку статуса HTTP, которая на самом деле относится к содержанию данных по индексу 0.Первый запрос вернул код 301 (постоянное перенаправление), так что обертка потока автоматически последовала этому перенаправлению, чтобы получить ответ 200 (индекс = 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', ...
- Функция Контекстные опции сокета() - Список контекстных опций сокета
- Функция Опции контекста HTTP() - Cписок опций контекста HTTP
- Функция Параметры контекста FTP() - Список параметров контекста FTP
- Функция Опции контекста SSL() - Список опций контекста SSL
- Функция Опции контекста CURL() - Список опций контекста CURL
- Функция Контекстные опции Phar () - Список контекстных опций Phar
- Функция MongoDB context options() - MongoDB context option listing
- Функция Параметры контекста() - Список параметров контекста
Коментарии
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.
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
$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";
}
?>
P>S> PHP 5.3.17
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 );
?>
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',
],
],
]));
?>
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.
)
);
. . .
?>
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).
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);
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(...))));
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(...))));
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)
It's worth noting that the `header` array seems to only want an array of strings, not an associative array.
I just spent a chunk of time debugging something not working as expected (no errors though) which was fixed by converting an associative array of headers into a simple array of strings.