PHP 日本大会 2024

stream_context_create

(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)

stream_context_create创建流上下文

描述

stream_context_create(?array $options = null, ?array $params = null): resource

创建并返回一个流上下文,其中包含在 options 中预设的任何选项。

参数

options

必须是关联数组的关联数组,格式为 $arr['wrapper']['option'] = $value,或 null。有关可用包装器和选项的列表,请参阅 上下文选项

默认为 null

params

必须是关联数组,格式为 $arr['parameter'] = $value,或 null。有关标准流参数列表,请参阅 上下文参数

返回值

一个流上下文 resource

变更日志

版本 描述
8.0.0 optionsparams 现在可以为空。

示例

示例 #1 使用 stream_context_create()

<?php
$opts
= [
'http' => [
'method' => "GET",
// 使用换行符 \n 分隔多个标头
'header' => "Accept-language: en\nCookie: foo=bar",
]
];

$context = stream_context_create($opts);

/* 向 www.example.com 发送 http 请求
使用上面显示的附加标头 */
$fp = fopen('http://www.example.com', 'r', false, $context);
fpassthru($fp);
fclose($fp);
?>

参见

添加注释

用户贡献的注释 11 条注释

jrubenstein at gmail dot com
17 年前
创建 SSL 流(使用 https://)时需要注意的一点

<?php
$context
= context_create_stream($context_options)
$fp = fopen('https://url', 'r', false, $context);
?>

人们可能会认为 - 创建流选项数组的正确方法如下所示

<?php
$context_options
= array (
'https' => array (
'method' => 'POST',
'header'=> "Content-type: application/x-www-form-urlencoded\r\n"
. "Content-Length: " . strlen($data) . "\r\n",
'content' => $data
)
);
?>

这是错误的方法!!!
请注意第 3 行:'https' => array (

正确的方法如下所示

<?php
$context_options
= array (
'http' => array (
'method' => 'POST',
'header'=> "Content-type: application/x-www-form-urlencoded\r\n"
. "Content-Length: " . strlen($data) . "\r\n",
'content' => $data
)
);
?>

注意,新的第 3 行:'http' => array (

现在 - 请记住这一点 - 我花了几个小时试图排除我的问题,当我最终偶然发现这个未记录的问题时。

向安全页面发布的完整代码如下所示

<?php
$data
= array ('foo' => 'bar', 'bar' => 'baz');
$data = http_build_query($data);

$context_options = array (
'http' => array (
'method' => 'POST',
'header'=> "Content-type: application/x-www-form-urlencoded\r\n"
. "Content-Length: " . strlen($data) . "\r\n",
'content' => $data
)
);

$context = context_create_stream($context_options)
$fp = fopen('https://url', 'r', false, $context);
?>
contact (at) thepointsolution.com
14 年前
我希望这能帮助到一些人。文档中没有提到的一点是,当 php 使用 --with-curlwrappers 编译时,

因此,而不是

<?php
$opts
= array(
'http'=>array(
'method'=>"GET",
'header'=>"Accept-language: en\r\n" .
"Cookie: foo=bar\r\n"
)
);

$context = stream_context_create($opts);
?>

您将以这种方式设置标头

<?php
$opts
= array(
'http'=>array(
'method'=>"GET",
'header'=>array("Accept-language: en",
"Cookie: foo=bar",
"Custom-Header: value")
)
);

$context = stream_context_create($opts);
?>

这段代码有效。
net_navard at yahoo dot com
18年前
您好,您可以创建一个参数数组(称为流上下文),每次通过套接字读取或写入流时都可以传输这些参数。在下面的示例中

$opts =array('http'=>arra('method'=>"GET",
'header'=>"Accept-language:en\r\n"."Cookie: foo=bar\r\n");

您实际上是在创建一组参数(要使用的协议、请求方法、附加的HTTP标头和Cookie),每次打开套接字连接以请求www.example.com时都会使用这些参数。如果您想在每次向www.example.com发出请求时都包含这些参数(称为流上下文),而不是一遍遍地指定它们,这将节省大量时间。
使用之前的示例,假设您想创建一个流上下文,该上下文发送一个“Content-Type”HTTP标头并在向www.example.com发出请求时使用它。请看

$opts = array('http'=>array('method'=>"GET",
'header'=>"Content-Type: text/xml; charset=utf-8");

$context = stream_context_create($opts);
$fp = fopen('http://www.example.com','r',false,$context);
fpassthru($fp);
fclose($fp);

现在,当您向www.example.com发出请求时,上述HTTP标头将包含在套接字中并传输到服务器。祝朋友们好运,Hossein
Ben J
11年前
我花了五个小时才弄明白这一点,所以希望它能为其他人节省一些时间。

当您尝试通过HTTP代理通过FTP下载文件时,请注意以下内容是不够的
<?php
$opts
= array('ftp' => array(
'proxy' => 'tcp://vbinprst10:8080',
'request_fulluri'=>true,
'header' => array(
"Proxy-Authorization: Basic $auth"
)
)
);
$context = stream_context_create($opts);
$s = file_get_contents("ftp://anonymous:[email protected]",false,$context);
?>

您的代理将响应需要身份验证。您可能会挠头并想:“但是我已经提供身份验证了!”

问题是'header'值仅适用于HTTP连接。因此,要在代理上进行身份验证,您必须先从HTTP提取文件,然后上下文才能用于FTP。
<?php
$opts
= array('ftp' => array(
'proxy' => 'tcp://vbinprst10:8080',
'request_fulluri'=>true,
'header' => array(
"Proxy-Authorization: Basic $auth"
)
),
'http' => array(
'proxy' => 'tcp://vbinprst10:8080',
'request_fulluri'=>true,
'header' => array(
"Proxy-Authorization: Basic $auth"
)
)
);
$context = stream_context_create($opts);
$s = file_get_contents("http://www.example.com",false,$context);
$s = file_get_contents("ftp://anonymous:[email protected]",false,$context);
?>

这有点迂回,但它有效。请注意,ftp数组中的'header'值是冗余的,但我还是保留了它。
davep at atomicdroplet dot com
17 年前
除了上面提到的上下文选项(附录N)之外,套接字的较低上下文选项可以在附录P中找到 - https://php.net/manual/en/transports.php
louis dot huppenbauer at gmail dot com
12年前
使用https协议时,您必须确保设置正确的上下文选项才能使用ssl/tls加密的全部“功能”。

<?php
$url
= 'https://secure.example.com/test/1';
$contextOptions = array(
'ssl' => array(
'verify_peer' => true,
'cafile' => __DIR__ . '/cacert.pem',
'verify_depth' => 5,
'CN_match' => 'secure.example.com'
)
);
$sslContext = stream_context_create($contextOptions);
$result = file_get_contents($url, NULL, $sslContext);
?>

有关这些上下文选项的更多信息,请访问https://php.net/manual/en/context.ssl.php
Andi
9年前
不要尝试重复使用`stream_context_create`返回的资源。使用https连接到不同的域名时,这似乎不起作用。
rlintern at gmail dot com
15年前
我发现以下代码对将一些二进制数据POST到远程服务器有效。我把它放在这里,因为我无法通过“谷歌搜索”或查看此文档快速找到解决方案。

免责声明:由于我是PHP新手,我不知道这是否是“好”的解决方案,但它可能适合您的需求,就像它适合我的需求一样。我假设对于非常大的文件,由于整个文件都读取到$fileContents中,因此会发生不好的事情。

我使用的是PHP 5.2.8。

$fileHandle = fopen("someImage.jpg", "rb");
$fileContents = stream_get_contents($fileHandle);
fclose($fileHandle);

$params = array(
'http' => array
(
'method' => 'POST',
'header'=>"Content-Type: multipart/form-data\r\n",
'content' => $fileContents
)
);
$url = "http://somesite.somecompany.com?someParam=someValue";
$ctx = stream_context_create($params);
$fp = fopen($url, 'rb', false, $ctx);

$response = stream_get_contents($fp);
Brian Gottier
15年前
在某些情况下,根据服务器配置,将标头选项设置为数组,而不是字符串。

<?php
$opts
= array(
'http'=> array(
'method'=> "GET",
'header'=> array( "Cookie: foo="bar"l ),
'user_agent'=>
$_SERVER['HTTP_USER_AGENT']
)
);
?>
mathieu dot laurent at gmail dot com
15年前
通过代理连接

<?php

$opts
= array('http' => array('proxy' => 'tcp://127.0.0.1:8080', 'request_fulluri' => true));
$context = stream_context_create($opts);

$data = file_get_contents('https://php.net', false, $context);

echo
$data;

?>
sp0n9e at gmail dot com
17 年前
这是一个非常简单的方法,可以轻松地进行POST操作,而无需使用cURL或手动编写HTTP请求,使用tcp://包装器。我喜欢使用上下文,仅仅是因为它们无处不在,而且不需要像cURL这样的可选库(尽管它是更流行的库之一)。

<?php

$options
= array(
'http'=>array(
'method'=>"POST",
'header'=>
"Accept-language: en\r\n".
"Content-type: application/x-www-form-urlencoded\r\n",
'content'=>http_build_query(array('foo'=>'bar'))
));

$context = stream_context_create($options);

fopen('http://www.example.com/',false,$context);

?>
To Top