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

PHP 模擬 POST/GET 請求完整指南:fsockopen、cURL、HttpClient 三種方案對比

     編輯:PHP 綜合知識

方案一:原生 fsockopen(底層 Socket,無依賴)

<?php
function sock_post($url, $data, $timeout = 10) {
    $parsed = parse_url($url);
    $host = $parsed['host'];
    $path = $parsed['path'] ?? '/';
    $query = $parsed['query'] ?? '';
    $port = $parsed['port'] ?? 80;

    $fp = fsockopen($host, $port, $errno, $errstr, $timeout);
    if (!$fp) throw new Exception("Connect failed: $errstr ($errno)");

    $payload = is_array($data) ? http_build_query($data) : $data;
    $header = "POST $path HTTP/1.1\r\n";
    $header .= "Host: $host\r\n";
    $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
    $header .= "Content-Length: " . strlen($payload) . "\r\n";
    $header .= "Connection: Close\r\n\r\n";
    $header .= $payload;

    fwrite($fp, $header);
    $response = '';
    while (!feof($fp)) {
        $response .= fread($fp, 8192);
    }
    fclose($fp);

    // 簡易分離 header/body
    list($headers, $body) = explode("\r\n\r\n", $response, 2);
    return ['headers' => $headers, 'body' => $body];
}

// GET 封裝
function sock_get($url, $timeout = 10) {
    $parsed = parse_url($url);
    $host = $parsed['host'];
    $path = ($parsed['path'] ?? '/') . ($parsed['query'] ? '?' . $parsed['query'] : '');
    $port = $parsed['port'] ?? 80;

    $fp = fsockopen($host, $port, $errno, $errstr, $timeout);
    if (!$fp) throw new Exception("Connect failed: $errstr ($errno)");

    $header = "GET $path HTTP/1.1\r\nHost: $host\r\nConnection: Close\r\n\r\n";
    fwrite($fp, $header);
    $response = '';
    while (!feof($fp)) $response .= fread($fp, 8192);
    fclose($fp);
    list($headers, $body) = explode("\r\n\r\n", $response, 2);
    return ['headers' => $headers, 'body' => $body];
}

方案二:cURL(功能豐富、效能最佳、標準選擇)

<?php
function curl_request($url, $method = 'GET', $data = null, $options = []) {
    $ch = curl_init();
    $defaultOpts = [
        CURLOPT_URL            => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 10,
        CURLOPT_CONNECTTIMEOUT => 5,
        CURLOPT_SSL_VERIFYPEER => false, // 生產環境請設 true 並配置 CA
        CURLOPT_SSL_VERIFYHOST => 2,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_MAXREDIRS      => 5,
        CURLOPT_USERAGENT      => 'Mozilla/5.0 (PHP/' . PHP_VERSION . ')',
        CURLOPT_HEADER         => true, // 回傳含 header
    ];
    if ($method === 'POST') {
        $defaultOpts[CURLOPT_POST] = true;
        $defaultOpts[CURLOPT_POSTFIELDS] = is_array($data) ? http_build_query($data) : $data;
    }
    curl_setopt_array($ch, array_merge($defaultOpts, $options));
    $response = curl_exec($ch);
    $errno = curl_errno($ch);
    $error = curl_error($ch);
    $info = curl_getinfo($ch);
    curl_close($ch);

    if ($errno) throw new Exception("cURL error $errno: $error");
    $headerSize = $info['header_size'];
    return [
        'headers' => substr($response, 0, $headerSize),
        'body'    => substr($response, $headerSize),
        'info'    => $info,
    ];
}

方案三:HttpClient 庫(ICUTIO HttpClient,輕量封裝)

<?php
require 'HttpClient.php'; // 官網 https://scripts.incutio.com/httpclient/

// 靜態快速 POST
$resp = HttpClient::quickPost('https://api.example.com/endpoint', [
    'name'  => 'John',
    'email' => 'john@example.com',
]);
echo $resp;

// 完整控制
$client = new HttpClient('api.example.com');
$client->setDebug(true);
$client->setUserAgent('MyApp/1.0');
$client->setAuthorization('Bearer', 'token123');
if ($client->post('/endpoint', ['foo' => 'bar'])) {
    $body = $client->getContent();
    $headers = $client->getHeaders();
    $status = $client->getStatus();
}

三方案對比

維度fsockopencURLHttpClient
依賴無(核心)需 curl 擴充需引入類別檔
HTTPS需自行實作 SSL原生支援支援(底層用 fsockopen/cURL)
Cookie/Session手動管理CURLOPT_COOKIEJAR/FILE內建管理
檔案上傳手動組 multipartCURLFile (PHP 5.5+)支援
代理手動原生支援
效能中高(連線複用、多工)中
維護性低(樣板碼多)中高(語意化 API)

生產環境建議

  1. 首選 cURL:功能完整、效能佳、社群支援廣。封裝成 Service 類別統一管理超時、重試、日誌、熔斷。
  2. 現代替代:Guzzle 7(PSR-18、PSR-7、Middleware、非同步)、Symfony HttpClient、Saloon(API 整合導向)。
  3. 安全:驗證 SSL 憑證、限制重導向次數、設定嚴格超時、過濾回應內容、記錄審計日誌。
  4. 測試:用 Mock Handler(Guzzle)或 php-vcr 錄製/重播 HTTP 互動。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved