首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP stream_context_create() 詳解:建立自訂串流上下文實現 HTTP 請求、Proxy、檔案上傳

     編輯:PHP 綜合知識

前言

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 回呼)
  • 回傳:串流上下文資源,傳遞給支援 context 參數的函數

範例一:自訂 HTTP 標頭與方法

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

範例三:HTTP Proxy 代理

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

範例四:multipart/form-data 檔案上傳(完整實作)

<?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 選項速查表

Wrapper常用選項說明
http/httpsmethod, header, content, timeout, proxy, request_fulluri, follow_location, max_redirects, ignore_errors, user_agentHTTP 客戶端核心選項
ftp/ftpsoverwrite, resume_pos, proxyFTP 上傳下載控制
ssl/tlsverify_peer, verify_peer_name, cafile, capath, local_cert, local_pk, passphrase, CN_matchSSL/TLS 憑證驗證
socketbindto, backlog, so_reuseport低階 Socket 綁定

優缺點與選擇建議

面向stream_contextcURL
依賴核心內建,無額外擴充需 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 開發者工具箱中的利器。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved