PHP Conference Japan 2024

HTTP 上下文选项

HTTP 上下文选项HTTP 上下文选项列表

描述

用于 http://https:// 传输的上下文选项。

选项

method 字符串

GETPOST 或远程服务器支持的任何其他 HTTP 方法。

默认为 GET

header 数组字符串

请求期间要发送的其他标头。此选项中的值将覆盖其他值(例如 User-agent:Host:Authentication:),即使在遵循 Location: 重定向时也是如此。因此,如果启用了 follow_location,则不建议设置 Host: 标头。

user_agent 字符串

要与 User-Agent: 标头一起发送的值。仅当上述 header 上下文选项中指定 user-agent 时,才会使用此值。

默认情况下,使用 user_agent php.ini 设置。

content 字符串

在标头之后发送的其他数据。通常与 POST 或 PUT 请求一起使用。

proxy 字符串

指定代理服务器地址的 URI(例如 tcp://proxy.example.com:5100)。

request_fulluri 布尔值

设置为 true 时,在构造请求时将使用整个 URI(例如 GET http://www.example.com/path/to/file.html HTTP/1.0)。虽然这是一种非标准的请求格式,但某些代理服务器需要它。

默认为 false

follow_location 整数

遵循 Location 标头重定向。设置为 0 以禁用。

默认为 1

max_redirects 整数

要遵循的最大重定向次数。值 1 或更小表示不遵循任何重定向。

默认为 20

protocol_version 浮点数

HTTP 协议版本。

从 PHP 8.0.0 开始默认为 1.1;在此版本之前,默认为 1.0

timeout 浮点数

以秒为单位的读取超时,由 浮点数 指定(例如 10.5)。

默认情况下,使用 default_socket_timeout php.ini 设置。

ignore_errors 布尔值

即使在失败的状态码上也获取内容。

默认为 false

示例

示例 #1 获取页面并发送 POST 数据

<?php

$postdata
= http_build_query(
array(
'var1' => 'some content',
'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 状态行
当此流包装器遵循重定向时,stream_get_meta_data() 返回的 wrapper_data 可能不一定包含实际应用于索引 0 处内容数据的 HTTP 状态行。

array (
  'wrapper_data' =>
  array (
    0 => 'HTTP/1.0 301 Moved Permanently',
    1 => 'Cache-Control: no-cache',
    2 => 'Connection: close',
    3 => 'Location: http://example.com/foo.jpg',
    4 => 'HTTP/1.1 200 OK',
    ...
第一个请求返回了 301(永久重定向),因此流包装器自动遵循重定向以获取 200 响应(索引 = 4)。

添加注释

用户贡献的注释 11 条注释

nate
10 年前

请注意,如果将 `protocol_version` 选项设置为 1.1,并且您请求的服务器配置为使用持久连接,则函数(`fopen`、`file_get_contents` 等)将“变慢”并需要很长时间才能完成。这是 HTTP 1.1 协议的一个特性,您不太可能在 PHP 中的流上下文使用它。

只需在请求中添加一个“Connection: close”头以消除持久连接超时。

<?php
// php 5.4 : 数组语法和带有数组值的header选项
$data = file_get_contents('http://www.example.com/', null, stream_context_create([
'http' => [
'protocol_version' => 1.1,
'header' => [
'Connection: close',
],
],
]));
?>
daniel dot peder at gmail dot com
7 年前
请注意,对于 http 和 https 协议,都需要相同的“http”上下文关键字。

<?php

// 正确的示例:
// 这将按预期工作
// 注意带有 https 的 url 但上下文为 http
$correct_data = file_get_contents('https://example.com', false, stream_context_create(array('http' => array(...))));

// 无效的示例:
// 这将无法工作,上下文将被忽略
// 注意带有 https 的 url 以及上下文为 https
$correct_data = file_get_contents('https://example.com', false, stream_context_create(array('https' => array(...))));
daniel.peder (a) gmail.com
7 年前
请注意,http 和 https 传输都需要相同的上下文名称 http。

// 正确示例
// 这将按预期工作
// 注意带有 https 的 url 但上下文为 http
$correct_data = file_get_contents('https://example.com', false, stream_context_create(array('http' => array(...))));

// 无效示例
// 这将无法工作,上下文将被忽略
// 注意带有 https 的 url 以及上下文为 https
$correct_data = file_get_contents('https://example.com', false, stream_context_create(array('https' => array(...))));
ASchmidt at Anamera dot net
3 年前
在默认情况下

'follow_location' => 1

请务必**不要**在“header”数组中包含“Host:”头。

如果主机设置为“mydomain.com”,并且该网站有一个(非常常见)重定向到“www.mydomain.com”,那么对“http://mydomain.com”的初始请求将得到预期的响应

HTTP/1.1 301 Moved Permanently
Location: http://www.mydomain.com/

但是,后续请求**不会**用新的“location”值替换原始的“host”头,正如人们预期的那样。因此,每个“follow_location”请求都将再次由原始主机“http://mydomain.com”提供服务,并继续重定向循环,直到“max_redirects”耗尽。

(详情请参阅:https://bugs.php.net/bug.php?id=77889
ywarnier at beeznest dot org
7 年前
请注意,将 `request_fulluri` 设置为 true 将**更改**接收端 `$_SERVER['REQUEST_URI]` 的值(从 `/abc.php` 到 http://domain.com/abc.php)。
gourav sarkar
13 年前
使用方法(POST 和 GET)时要注意大小写...它必须始终为大写。如果您使用小写,则无法正常工作。
aruntechguy at outlook dot com
7 年前
如果您想在使用 `get_headers()` 时使用基本身份验证,请使用以下流上下文选项。

我在这里使用 HEAD 方法,但请随意使用 GET。

<?php
$targetUrl
= '此处为 http 或 https 目标 url';
$basicAuth = base64_encode('username:password');

stream_context_set_default(
[
'http' => [
'method' => 'HEAD',
'header' => 'Authorization: Basic ' . $basicAuth
]
]
);
$result = get_headers($targetUrl);

print_r($result);
njt1982 at yahoo dot com
5 个月前
值得注意的是,`header` 数组似乎只希望一个字符串数组,而不是关联数组。

我刚刚花了一段时间调试某些东西无法按预期工作(但没有错误),通过将头文件的关联数组转换为简单的字符串数组解决了这个问题。
vchampion at gmail dot com
12 年前
如果您使用代理服务器并遇到错误“`fopen(http://example.com): failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request`”,请注意,在许多情况下,您还需要在流选项中将参数“request_fulluri”设置为“true”。如果没有此选项,php 脚本将向服务器发送空请求作为“GET / HTTP/0.0”,并且代理服务器将使用“HTTP 400”错误进行回复。

例如(工作示例)
<?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 /* 没有此选项,我们将收到 HTTP 错误! */
)));

if (
$fp = fopen("http://example.com", 'r', false, $stream) ) {
print
"操作成功";
}
?>

附注:PHP 5.3.17
jay
9 年前
请记住使内容与 Content-type 匹配。

<?php

$data
= array(
'var1' => 'some content',
'var2' => 'doh'
);

$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/json', // 在这里...
'content' => json_encode($data) // 以及这里。
)
);

. . .

?>
chris
10 年前

我尝试通过代理服务器向安全 url 发出 `fopen` 请求时遇到了很多麻烦。我不断收到远程主机返回的 400 错误请求。它正在接收代理 url 作为 SNI 主机。为了解决这个问题,我不得不明确地将 SNI 主机设置为我尝试访问的域名。这显然是此错误中概述的问题

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 );
?>
To Top