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

PHP Socket 實現 POST 請求:底層網絡通訊實戰

     編輯:PHP 相關知識

PHP Socket 實現 POST 請求:底層網絡通訊實戰

在無 cURL 擴展、或需精細控制 TCP 連接(如自定義 Header、Keep-Alive、非標準端口)時,使用 fsockopen 手工構造 HTTP 請求是核心技能。本文封裝 post_request() 函數,演示完整的 Socket 級 POST 流程。

核心函數實現

function post_request($url, $data, $referer = '') {
    // 1. 將關聯數組編碼為 application/x-www-form-urlencoded
    $data = http_build_query($data);

    // 2. 解析 URL
    $parsed = parse_url($url);
    if ($parsed['scheme'] !== 'http') {
        die('Error: Only HTTP supported!');
    }
    $host = $parsed['host'];
    $path = $parsed['path'] ?: '/';

    // 3. 建立 Socket 連接(超時 30s)
    $fp = fsockopen($host, 80, $errno, $errstr, 30);
    if (!$fp) {
        return ['status' => 'err', 'error' => "$errstr ($errno)"];
    }

    // 4. 發送請求頭與 Body
    $request = "POST $path HTTP/1.1\r\n";
    $request .= "Host: $host\r\n";
    if ($referer) $request .= "Referer: $referer\r\n";
    $request .= "Content-Type: application/x-www-form-urlencoded\r\n";
    $request .= "Content-Length: " . strlen($data) . "\r\n";
    $request .= "Connection: close\r\n\r\n";
    $request .= $data;

    fwrite($fp, $request);

    // 5. 讀取響應
    $response = '';
    while (!feof($fp)) {
        $response .= fgets($fp, 128);
    }
    fclose($fp);

    // 6. 分離 Header 與 Body
    list($header, $content) = explode("\r\n\r\n", $response, 2) + ['', ''];
    return ['status' => 'ok', 'header' => $header, 'content' => $content];
}

調用示例

$post_data = ['test' => 'foobar', 'okay' => 'yes', 'number' => 2];
$result = post_request('https://www.example.com/', $post_data);

if ($result['status'] === 'ok') {
    echo "Header:\n" . $result['header'] . "\n
\nBody:\n" . $result['content']; } else { echo "Error: " . $result['error']; }

關鍵細節解析

  • HTTP/1.1 必須發送 Host 頭,否則虛擬主機環境下會返回 400。
  • Content-Length 必須精確等於 Body 字節長度。
  • Connection: close 避免 Keep-Alive 導致 feof() 陷入等待。
  • HTTPS 支援:需改用 fsockopen('ssl://'.$host, 443) 並處理 SSL 證書驗證。

對比 cURL

生產環境建議

除非極端受限環境,首選 cURL 或 Guzzle/GuzzleHttp。Socket 方案適合教學、嵌入式、無擴展權限的舊系統維護。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
特性Socket (fsockopen)cURL
依賴核心函數,無擴展依賴需安裝 php-curl
HTTPS手工處理 SSL 上下文內建支援
重定向需手工解析 Location 並遞歸CURLOPT_FOLLOWLOCATION
超時控制連接/讀寫分離較麻煩CURLOPT_CONNECTTIMEOUT/CURLOPT_TIMEOUT
性能較低(用戶態實現)高(C 底層)