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

PHP 串流上下文實作 HTTP 請求函式

     編輯:PHP 相關知識

PHP 內建 stream_context_create 配合 file_get_contents 即可完成 HTTP GET/POST 請求,無需安裝 cURL 擴充。本文封裝一個通用的 http_open 函式,支援自訂 Header、Cookie、Timeout、User-Agent。

函式完整碼

<?php
function http_open($url, $data = '', $cookie = null, $method = 'GET', $timeout = 60) {
    $options = [
        'http' => [
            'method'      => strtoupper($method),
            'user_agent'  => $_SERVER['HTTP_USER_AGENT'] ?? 'PHP/' . PHP_VERSION,
            'timeout'     => $timeout,
            'ignore_errors' => true, // 取得 4xx/5xx 回應內容
        ]
    ];
    
    if ($method === 'POST') {
        $options['http']['header'] = [
            'Content-type: application/x-www-form-urlencoded',
            'Content-Length: ' . strlen($data),
            'Connection: close',
        ];
        if ($cookie) $options['http']['header'][] = "Cookie: $cookie";
        $options['http']['content'] = $data;
    } else {
        $options['http']['header'] = [
            'Content-type: application/x-www-form-urlencoded',
            'Connection: close',
        ];
        if ($cookie) $options['http']['header'][] = "Cookie: $cookie";
    }
    
    $context = stream_context_create($options);
    $result = @file_get_contents($url, false, $context);
    
    // 可選:檢查 HTTP 狀態碼
    // $meta = stream_get_meta_data($fp); // 需用 fopen 方式取得
    
    return $result;
}

使用範例

<?php
// GET 請求
$html = http_open('https://api.example.com/users?page=1');
echo $html;

// POST 表單
$postData = http_build_query(['username' => 'haowei', 'action' => 'login']);
$resp = http_open('https://api.example.com/login', $postData, '', 'POST', 30);
var_dump($resp);

// 帶 Cookie
$cookie = 'session_id=abc123; theme=dark';
$resp = http_open('https://api.example.com/profile', '', $cookie);

進階:取得 HTTP 狀態碼與 Header

function http_open_full($url, $data = '', $method = 'GET', $headers = [], $timeout = 30) {
    $opts = [
        'http' => [
            'method'  => $method,
            'timeout' => $timeout,
            'header'  => $headers,
            'ignore_errors' => true,
        ]
    ];
    if ($data) $opts['http']['content'] = $data;
    
    $ctx = stream_context_create($opts);
    $fp = fopen($url, 'r', false, $ctx);
    if (!$fp) return false;
    
    $meta = stream_get_meta_data($fp);
    $content = stream_get_contents($fp);
    fclose($fp);
    
    // 解析狀態碼
    $statusLine = $meta['wrapper_data'][0] ?? '';
    preg_match('/\d{3}/', $statusLine, $m);
    $httpCode = $m[0] ?? 0;
    
    return [
        'code'    => (int)$httpCode,
        'headers' => $meta['wrapper_data'],
        'body'    => $content,
    ];
}

注意事項與限制

  • allow_url_fopen 必須在 php.ini 開啟(預設 On)。
  • 不支援多部分表單 multipart/form-data 檔案上傳,需改用 cURL。
  • 預設不驗證 SSL 憑證,生產環境建議加入 'verify_peer' => true, 'cafile' => '/path/to/cacert.pem'。
  • 大檔案下載會佔用記憶體,串流處理請用 fopen + fread 迴圈。
  • 並發請求效能不如 cURL 多執行緒,高併發場景請改用 Guzzle / cURL multi。

何時選用 stream vs cURL

場景建議
簡單 GET/POST API 呼叫stream_context (零依賴)
檔案上傳 / 多部分表單cURL / Guzzle
需精細控制 SSL / 憑證 / ProxycURL
高併發 / 非同步 / 連線重用cURL multi / Swoole / Guzzle async
舊版 PHP / 受限環境無 cURLstream_context

善用串流上下文能輕量完成大多數 HTTP 整合需求,減少專案依賴。

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