stream_context_create() 是 PHP 串流擴充的核心函數,允許為 fopen()、file_get_contents()、stream_socket_client() 等檔案/網路操作建立自訂上下文(Context),支援 HTTP 方法、標頭、Proxy、SSL、超時等細粒度控制,是不引入 cURL 依賴時的輕量替代方案。
stream_context_create(array $options = [], array $params = []): resource
$options:協定專用選項陣列,結構為 ['wrapper' => ['option' => value]]$params:通用參數(如 notification 回呼)<?php
$opts = [
'http' => [
'method' => 'GET',
'header' => "Accept-Language: en\r\n" .
"Cookie: foo=bar\r\n" .
"User-Agent: MyApp/1.0\r\n",
'timeout' => 10, // 秒
],
];
$ctx = stream_context_create($opts);
$fp = fopen('https://www.example.com', 'r', false, $ctx);
if ($fp) {
stream_copy_to_stream($fp, STDOUT);
fclose($fp);
}
注意:header 可為字串(含 \r\n)或陣列(每項一行),陣列更易維護。
<?php
$opts = [
'http' => [
'method' => 'GET',
'header' => [
'Accept-Language: en',
'Cookie: foo=bar',
'Custom-Header: value',
],
'timeout' => 15,
'ignore_errors' => true, // 取得 4xx/5xx 內容
'follow_location' => 1, // 跟隨重導向
'max_redirects' => 5,
],
];
$ctx = stream_context_create($opts);
$data = file_get_contents('https://api.example.com/data', false, $ctx);
<?php
$opts = [
'http' => [
'proxy' => 'tcp://127.0.0.1:8080',
'request_fulluri' => true, // 使用絕對 URI 請求
'header' => [
'Proxy-Authorization: Basic ' . base64_encode('user:pass'),
],
],
];
$ctx = stream_context_create($opts);
$data = file_get_contents('https://www.example.com', false, $ctx);
<?php
function doPostRequest(string $url, array $postData, array $files = []): string
{
$boundary = '------------------' . substr(md5((string)mt_rand()), 0, 10);
$body = '';
// 一般欄位
foreach ($postData as $key => $val) {
$body .= "--$boundary\r\n";
$body .= "Content-Disposition: form-data; name=\"$key\"\r\n\r\n";
$body .= "$val\r\n";
}
// 檔案欄位
foreach ($files as $key => $file) {
$content = file_get_contents($file['tmp_name']);
$body .= "--$boundary\r\n";
$body .= "Content-Disposition: form-data; name=\"$key\"; filename=\"{$file['name']}\"\r\n";
$body .= "Content-Type: {$file['type']}\r\n";
$body .= "Content-Transfer-Encoding: binary\r\n\r\n";
$body .= "$content\r\n";
}
$body .= "--$boundary--\r\n";
$opts = [
'http' => [
'method' => 'POST',
'header' => "Content-Type: multipart/form-data; boundary=$boundary\r\n" .
"Content-Length: " . strlen($body) . "\r\n",
'content' => $body,
],
];
$ctx = stream_context_create($opts);
$fp = fopen($url, 'rb', false, $ctx);
if (!$fp) throw new Exception("無法開啟串流: $url");
$response = stream_get_contents($fp);
fclose($fp);
return $response;
}
// 使用範例
$postData = ['name' => 'John', 'age' => 30];
$files = ['avatar' => $_FILES['avatar']];
echo doPostRequest('https://api.example.com/upload', $postData, $files);
| Wrapper | 常用選項 | 說明 |
|---|---|---|
| http/https | method, header, content, timeout, proxy, request_fulluri, follow_location, max_redirects, ignore_errors, user_agent | HTTP 客戶端核心選項 |
| ftp/ftps | overwrite, resume_pos, proxy | FTP 上傳下載控制 |
| ssl/tls | verify_peer, verify_peer_name, cafile, capath, local_cert, local_pk, passphrase, CN_match | SSL/TLS 憑證驗證 |
| socket | bindto, backlog, so_reuseport | 低階 Socket 綁定 |
| 面向 | stream_context | cURL |
|---|---|---|
| 依賴 | 核心內建,無額外擴充 | 需 php-curl 擴充 |
| 功能豐富度 | 基礎 HTTP/SSL/Proxy | 完整 HTTP/2、多重請求、WebSocket 等 |
| 效能 | 單請求足夠 | 高併發、連線重用更優 |
| 易用性 | 陣列配置直觀 | 選項眾多,學習曲線較陡 |
建議:簡單 GET/POST、無高併發需求、不想加依賴 → stream_context;API 客戶端、爬蟲、長連線、HTTP/2 → cURL/Guzzle。
stream_context_create() 讓 PHP 內建檔案/網路函數具備專業級 HTTP 控制能力。掌握 http wrapper 選項結構,即可輕鬆實作自訂標頭、Proxy、檔案上傳、SSL 驗證等常見需求,是 PHP 開發者工具箱中的利器。