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

PHP Socket 實作 HTTP POST 請求發送資料到遠端伺服器

     編輯:PHP 綜合知識

底層 Socket 實作(教學用途)

<?php
/**
 * 使用 fsockopen 發送原始 HTTP POST 請求
 * @param string $url 目標 URL
 * @param array $data POST 欄位陣列
 * @param string $referer 可選 Referer
 * @return array ['status'=>'ok'|'err', 'header'=>'', 'content'=>'', 'error'=>'']
 */
function socketPostRequest($url, array $data, $referer = '') {
    // 1. 解析 URL
    $parsed = parse_url($url);
    if ($parsed['scheme'] !== 'http') {
        return ['status' => 'err', 'error' => '僅支援 HTTP'];
    }
    
    $host = $parsed['host'];
    $path = $parsed['path'] ?? '/';
    if (!empty($parsed['query'])) $path .= '?' . $parsed['query'];
    $port = $parsed['port'] ?? 80;
    
    // 2. 建構 POST 資料
    $postData = http_build_query($data);
    
    // 3. 開啟 Socket 連線
    $fp = fsockopen($host, $port, $errno, $errstr, 30);
    if (!$fp) {
        return ['status' => 'err', 'error' => "$errstr ($errno)"];
    }
    
    // 4. 發送 HTTP 請求
    $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($postData) . "\r\n";
    $request .= "Connection: close\r\n\r\n";
    $request .= $postData;
    
    fwrite($fp, $request);
    
    // 5. 讀取回應
    $response = '';
    while (!feof($fp)) {
        $response .= fgets($fp, 1024);
    }
    fclose($fp);
    
    // 6. 分離 Header 與 Body
    list($header, $content) = explode("\r\n\r\n", $response, 2) + ['', ''];
    
    return [
        'status' => 'ok',
        'header' => $header,
        'content' => $content
    ];
}

// 使用範例
$result = socketPostRequest('https://httpbin.org/post', [
    'username' => 'testuser',
    'action' => 'login',
    'timestamp' => time()
]);

if ($result['status'] === 'ok') {
    echo "Header:\n{$result['header']}\n\n";
    echo "Body:\n{$result['content']}\n";
} else {
    echo "錯誤:{$result['error']}\n";
}
?>

現代最佳實作:cURL / Guzzle(生產環境)

<?php
// cURL 版本
function curlPostRequest($url, array $data, array $options = []) {
    $ch = curl_init($url);
    curl_setopt_array($ch, array_merge([
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => http_build_query($data),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_CONNECTTIMEOUT => 10,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_MAXREDIRS => 5,
        CURLOPT_SSL_VERIFYPEER => true, // 生產環境必須驗證
        CURLOPT_HTTPHEADER => [
            'User-Agent: MyApp/1.0',
            'Accept: application/json',
        ],
    ], $options));
    
    $response = curl_exec($ch);
    $errno = curl_errno($ch);
    $error = curl_error($ch);
    $info = curl_getinfo($ch);
    curl_close($ch);
    
    if ($errno) {
        return ['status' => 'err', 'error' => $error, 'errno' => $errno];
    }
    
    return [
        'status' => 'ok',
        'http_code' => $info['http_code'],
        'content' => $response,
        'header_size' => $info['header_size'],
    ];
}

// Guzzle HTTP Client(推薦現代框架專案)
// composer require guzzlehttp/guzzle
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

$client = new Client([
    'timeout' => 30,
    'headers' => ['User-Agent' => 'MyApp/1.0'],
]);

try {
    $response = $client->post('https://api.example.com/endpoint', [
        'form_params' => ['key' => 'value'],
        'json' => ['nested' => ['data' => 123]], // 自動 JSON 編碼
    ]);
    
    $data = json_decode($response->getBody()->getContents(), true);
    echo "狀態碼: {$response->getStatusCode()}\n";
    print_r($data);
} catch (RequestException $e) {
    echo "請求失敗: {$e->getMessage()}\n";
    if ($e->hasResponse()) {
        echo "回應: " . $e->getResponse()->getBody() . "\n";
    }
}
?>

關鍵差異比較

特性fsockopencURLGuzzle
HTTPS 支援需手動實作 SSL原生支援原生支援
錯誤處理手動解析錯誤碼/訊息例外物件
重導向手動處理自動跟隨自動跟隨
Cookie 管理手動Cookie JarCookie Jar
並發請求不支援curl_multiPromise/Pool
Middleware/Plugin無無豐富生態
適用場景教學、極簡環境一般專案現代框架專案

安全性檢查清單

  • ✅ 生產環境強制 CURLOPT_SSL_VERIFYPEER => true
  • ✅ 設定合理 CURLOPT_TIMEOUT 避免阻塞
  • ✅ 驗證回應 HTTP 狀態碼(2xx 成功)
  • ✅ 敏感資料(Token、密碼)不記錄日誌
  • ✅ 使用 http_build_query 正確編碼 POST 資料
  • ✅ 設定 User-Agent 識別應用身分
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved