當檔案較大或不想載入整個檔案到記憶體時,使用 HTTP 串流傳輸是不二之選。本文提供完整的發送端與接收端程式碼,採用 php://input 讀取原始 POST 資料,搭配 stream_context_create 發送二進位內容。
<?php
/**
* 以串流方式發送檔案
* @param string $url 接收端 URL
* @param string $file 要發送的本地檔案路徑
* @return bool
*/
function sendStreamFile($url, $file) {
if (!file_exists($file)) {
return false;
}
$opts = [
'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/octet-stream',
'content' => file_get_contents($file),
]
];
$context = stream_context_create($opts);
$response = file_get_contents($url, false, $context);
$ret = json_decode($response, true);
return $ret['success'] ?? false;
}
$ret = sendStreamFile('https://localhost/receiveStreamFile.php', 'send.txt');
var_dump($ret);
?>
<?php
/**
* 接收串流檔案並儲存
* @param string $receiveFile 儲存路徑
* @return bool
*/
function receiveStreamFile($receiveFile) {
// 相容舊版 PHP 的 $HTTP_RAW_POST_DATA
$streamData = $GLOBALS['HTTP_RAW_POST_DATA'] ?? '';
// 標準方式讀取原始輸入串流
if (empty($streamData)) {
$streamData = file_get_contents('php://input');
}
if ($streamData !== '') {
$ret = file_put_contents($receiveFile, $streamData);
return $ret !== false;
}
return false;
}
$receiveFile = 'receive.txt';
$ret = receiveStreamFile($receiveFile);
echo json_encode(['success' => (bool)$ret]);
?>
application/octet-stream 而非表單編碼,避免資料被解析變形enable_post_data_reading 影響fopen() 分塊讀寫,避免 file_get_contents 佔用過多記憶體此模式可擴展為:斷點續傳(配合 Range 標頭)、多檔案打包串流(tar/zip 即時壓縮)、加密傳輸(OpenSSL 串流加密)等企業級檔案交換需求。