在 PHP 開發中,經常需要向遠端 API 發送 HTTP 請求。雖然 cURL 是常見選擇,但若環境未安裝 cURL 擴展,或需輕量級無相依的實作,使用原生 fsockopen 封裝的請求類別是不錯的替代方案。本文介紹一個支援 GET、POST、Multipart/form-data(檔案上傳) 三種模式的 HttpRequest 類別,並提供完整程式碼與使用範例。
setConfig():設定連線參數(IP、Host、Port、Timeout 等)setFormData():設定表單欄位資料setFileData():設定上傳檔案資訊(欄位名、檔名、路徑)send($type):發送請求,$type 可為 get、post、multipart<?php
class HttpRequest {
private $_ip = ''; private $_host = ''; private $_url = ''; private $_port = '';
private $_errno = ''; private $_errstr = ''; private $_timeout = 15;
private $_fp = null; private $_formdata = array(); private $_filedata = array();
public function setConfig($config) { /* 設定連線參數 */ }
public function setFormData($formdata=array()) { $this->_formdata = $formdata; }
public function setFileData($filedata=array()) { $this->_filedata = $filedata; }
public function send($type='get') {
$type = strtolower($type);
if (!in_array($type, array('get','post','multipart'))) return false;
if (!$this->connect()) return false;
switch($type) {
case 'get': $out = $this->sendGet(); break;
case 'post': $out = $this->sendPost(); break;
case 'multipart': $out = $this->sendMultipart(); break;
}
if (!$out) return false;
fputs($this->_fp, $out);
$response = '';
while ($row = fread($this->_fp, 4096)) $response .= $row;
$this->disconnect();
$pos = strpos($response, "\r\n\r\n");
return substr($response, $pos+4);
}
private function connect() { /* fsockopen 建立連線 */ }
private function disconnect() { /* fclose 關閉連線 */ }
private function sendGet() { /* 組裝 GET 請求 */ }
private function sendPost() { /* 組裝 POST application/x-www-form-urlencoded */ }
private function sendMultipart() { /* 組裝 multipart/form-data,含檔案 */ }
}
?>
<?php
require 'HttpRequest.class.php';
$config = array(
'ip' => 'demo.fdipzone.com',
'host' => 'demo.fdipzone.com',
'port' => 80,
'timeout' => 30,
'url' => '/multipart.php'
);
$formdata = array('name' => 'fdipzone', 'gender' => 'man');
$filedata = array(array('name' => 'photo', 'filename' => 'photo.jpg', 'path' => 'photo.jpg'));
$obj = new HttpRequest();
$obj->setConfig($config);
$obj->setFormData($formdata);
$obj->setFileData($filedata);
// 發送 multipart 請求(含檔案上傳)
$result = $obj->send('multipart');
echo '<pre>'; print_r($result); echo '</pre>';
?>
使用 md5(rand()) 產生唯一邊界字串,確保不與內容衝突。
透過 file_get_contents 讀取檔案二進位內容,mime_content_type() 偵測 MIME 型別。
讀取完整回應後,以 \r\n\r\n 分隔標頭與主體,僅回傳主體內容。
enctype="multipart/form-data" 表單中,type="file" 的輸入只能透過 $_FILES 取得,其他欄位才在 $_POST。
需將 Content-Type 設為 multipart/form-data,並手動組裝符合 RFC 2046 的主體格式(含 boundary、Content-Disposition 等)。
此 HttpRequest 類別無需 cURL 即可完成常見的 HTTP 互動,適合輕量專案或受限環境。若需支援 HTTPS、Cookie 管理、重導向追蹤等進階功能,建議改用 Guzzle 或 cURL 封裝庫。