在 PHP 開發中,自動化表單提交是常見需求,無論是串接第三方 API、模擬用戶登入,或是批次資料送出,掌握底層網路通訊技巧至關重要。本文將深入剖析兩大主流實作方式 —— fsockopen 與 cURL,提供完整程式碼範例與實戰建議,助你靈活應對各種提交場景。
兩者皆能發送 HTTP POST 請求,但設計哲學迥異:
以下封裝函式 post() 示範如何解析 URL、編碼資料、建立 Socket 連線、發送標準 HTTP/1.0 請求並讀取回應:
<?php
/**
* 使用 fsockopen 發送 POST 請求
* @param string $url 目標網址(含 scheme、host、port、path、query)
* @param array $data 要提交的鍵值對陣列
* @return string|false 伺服器回應內容,失敗回傳 false
*/
function post($url, $data) {
// 1. 解析 URL 結構
$url = parse_url($url);
if (!$url) return "無法解析 URL";
$url['port'] = $url['port'] ?? 80;
$url['path'] = $url['path'] ?? '/';
$url['query'] = $url['query'] ?? '';
// 2. 組裝 application/x-www-form-urlencoded 主體
$encoded = '';
foreach ($data as $k => $v) {
$encoded .= ($encoded ? '&' : '') . rawurlencode($k) . '=' . rawurlencode($v);
}
// 3. 建立 Socket 連線
$fp = fsockopen($url['host'], $url['port'], $errno, $errstr, 30);
if (!$fp) return "連線失敗:$errstr ($errno)";
// 4. 發送請求列、標頭與主體
$request = "POST {$url['path']}" . ($url['query'] ? "?{$url['query']}" : '') . " HTTP/1.0\r\n";
$request .= "Host: {$url['host']}\r\n";
$request .= "Content-Type: application/x-www-form-urlencoded\r\n";
$request .= "Content-Length: " . strlen($encoded) . "\r\n";
$request .= "Connection: close\r\n\r\n";
$request .= $encoded;
fwrite($fp, $request);
// 5. 讀取回應:先略過標頭,再取主體
$headerDone = false;
$response = '';
while (!feof($fp)) {
$line = fgets($fp, 1024);
if (!$headerDone) {
if ($line === "\r\n" || $line === "\n") $headerDone = true;
continue;
}
$response .= $line;
}
fclose($fp);
return $response;
}
// 使用範例
// $url = 'https://example.com/api/login';
// $data = ['user' => 'demo', 'pass' => 'secret'];
// echo post($url, $data);
?>
parse_url() 自動拆解 scheme、host、port、path、query,缺值需給預設。rawurlencode() 依 RFC 3986 規範編碼,避免特殊字元導致伺服器解析錯誤。\r\n 換行,Connection: close 確保讀完即斷線。cURL 將上述繁瑣流程封裝為簡單選項,幾行代碼即可完成同樣功能,並支援 HTTPS、User-Agent 偽裝、超時控制等進階需求:
<?php
$url = 'https://localhost/curl/result.php';
$params = 'param=123¶m2=333'; // 或傳入陣列:['param'=>123, 'param2'=>333]
$userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36';
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $params,
CURLOPT_USERAGENT => $userAgent,
CURLOPT_RETURNTRANSFER => true, // 直接回傳字串而非輸出
CURLOPT_TIMEOUT => 10, // 秒級超時
CURLOPT_SSL_VERIFYPEER => false, // 僅測試環境關閉 SSL 驗證
]);
$result = curl_exec($ch);
if ($result === false) {
echo 'cURL 錯誤:' . curl_error($ch);
} else {
echo "回應內容:
{$result}";
}
curl_close($ch);
?>
result.php<?php // 僅供測試:印出接收到的 $_POST print_r($_POST); ?>
curl_errno()、HTTP 狀態碼(curl_getinfo($ch, CURLINFO_HTTP_CODE))。CURLOPT_SSL_VERIFYPEER => true 並配置 CA 憑證。curl_multi_* 系列函式實現並發提交。Content-Type 改為 application/json,主體用 json_encode($data)。欲深入掌握 PHP 網路程式設計,建議參考:
掌握這兩大技法,讓你的 PHP 程式能靈活串接各類 Web 服務,輕鬆實現自動化表單提交與資料交換。