客戶端 (App、IoT 裝置、Webhook) 以原始二進制 POST 送圖片/檔案,非 multipart/form-data,PHP $_POST 無法解析,需讀取 Raw Body。
<?php
/**
* 將 Raw POST 資料儲存為檔案
* @param string $file 目標檔案路徑
* @return bool|int 寫入位元組數或 false
*/
function binary_to_file($file) {
// 1. 嘗試 $GLOBALS (需 php.ini: always_populate_raw_post_data = On,PHP 5.6+ 棄用)
$content = $GLOBALS['HTTP_RAW_POST_DATA'] ?? '';
// 2. 推薦:php://input 流 (不需配置、記憶體效率佳、支援大資料)
if (empty($content)) {
$content = file_get_contents('php://input');
}
// 3. 寫入檔案
return file_put_contents($file, $content, LOCK_EX);
}
// 使用範例
binary_to_file('photo/test.png');
| 特性 | $GLOBALS['HTTP_RAW_POST_DATA'] | php://input |
|---|---|---|
| PHP 版本 | 5.6 棄用,7.0 移除 | 所有版本支援 |
| 需配置 | always_populate_raw_post_data = On | 無 |
| 記憶體 | 完整載入記憶體 | 可流式讀取 (搭配 fopen/fread) |
| multipart/form-data | 不支援 | 不支援 |
| 建議 | ❌ 棄用 | ✅ 首選 |
function stream_to_file($file, $chunkSize = 8192) {
$in = fopen('php://input', 'rb');
$out = fopen($file, 'wb');
while (!feof($in)) {
$data = fread($in, $chunkSize);
fwrite($out, $data);
}
fclose($in); fclose($out);
}
application/octet-stream 或具體 MIME,不可為 multipart/form-data。php://input 只能讀取一次 (非 seekable),後續再讀將為空。需一次性讀完或暫存。php://input 讀取延遲,可關閉 fastcgi_request_buffering off。client_max_body_size)、掃描病毒。PHP 接收 Raw 二進制流的標準做法是 file_get_contents('php://input') 或流式 fopen('php://input')。棄用 $GLOBALS['HTTP_RAW_POST_DATA'],並注意 multipart/form-data 走 $_FILES 完全不同的處理路徑。掌握此差異,即可正確實現檔案上傳、Webhook 接收、IoT 數據收集等功能。