我从http传递到https,因此我必须添加一个StreamContext到几个read_file并get_file_contents调用.
我需要更换
read_file('http://'.$host.$uri);
Run Code Online (Sandbox Code Playgroud)
通过
$stream_context = stream_context_create([
/* some lenghty options array */
]);
read_file('https://'.$host.$uri, false, $stream_context);
Run Code Online (Sandbox Code Playgroud)
现在我的问题是:$ stream_context可重用如下:
$stream_context = stream_context_create([
/* some lenghty options array */
]);
read_file('https://'.$host.$uri, false, $stream_context);
get_file_contents($another_url, false, $stream_context);
read_file($even_another, false, $stream_context);
Run Code Online (Sandbox Code Playgroud)
或者我是否需要StreamContext为每个URL 重新创建一个新的?
问的不同:流上下文只是参数和选项的描述符,还是在使用时绑定到资源?
编辑:从评论中可以看出,人们可以StreamContext经常重复使用,但并非总是如此.作为答案,这不是很令人满意.
何时可以或应该重复使用,什么时候不能重复使用?能否有人对内部工作有所了解StreamContext.该文件看起来很稀疏我.
流上下文是可重用的,并且可以始终(而不是经常)重用。
@ilpaijin 指出“不可预测的行为评论”的评论很简单,是对作者留下评论的误解。
当您为 HTTP 包装器指定上下文时,无论您的目标架构是什么,都可以将包装器指定为 HTTP,这意味着不存在 HTTPS 包装器之类的东西。
如果您尝试执行以下操作:
"https" => [
// options will not be applied to HTTPS stream as there is no such wrapper (https)
]
Run Code Online (Sandbox Code Playgroud)
正确的做法:
"http" => [
// options will apply to http:// and https:// streams.
]
Run Code Online (Sandbox Code Playgroud)
什么时候应该/可以重新使用?
这实际上取决于您以及您想要实现的逻辑。
不要忘记您已经为所有本机 PHP 包装器设置了默认上下文。
您发布的示例中,将相同的上下文流传递给 3 个不同的调用是不必要的,只需使用stream_context_set_default并为源自代码的请求设置默认上下文。
在某些情况下,您设置默认值,但对于一个特定请求,您希望拥有不同的上下文,最好创建另一个流并将其传入。
流上下文是否包含状态,例如从一个调用传递到另一个调用的 cookie 或 tls 初始协商?
流上下文不包含状态,但是您可以使用附加代码实现这样的模拟。任何状态,无论是 cookie 还是 TLS 握手,都只是请求标头。您需要从传入请求中读取该信息并将其设置在流中,然后将该流传递给其他请求,从而模拟父请求的“状态”。话虽如此 - 不要这样做,只需使用CURL。
从一方面来说,流的真正力量是创建您自己的/自定义流。使用 CURL 可以更轻松(且更好)地实现标头操作和状态控制。