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

PHP 接收原始二進制流數據並生成文件(支援 php://input 與 HTTP_RAW_POST_DATA)

     編輯:PHP 相關知識

PHP 接收原始二進制流數據並生成文件(支援 php://input 與 HTTP_RAW_POST_DATA)

當客戶端以 Content-Type: application/octet-stream 或非表單編碼方式發送二進制數據(如圖片上傳、設備上報)時,$_POST 無法解析。需通過 php://input 或 $GLOBALS['HTTP_RAW_POST_DATA'] 讀取原始流。本文封裝通用函數並說明適用場景與避坑指南。

核心函數:binary_to_file()

<?php
/**
 * 將請求體原始二進制流保存為文件
 *
 * @param string $file 目標文件路徑(含文件名)
 * @return bool|int 寫入字節數,失敗返回 false
 */
function binary_to_file($file) {
    // 1. 優先嘗試 $GLOBALS['HTTP_RAW_POST_DATA'](需 php.ini: always_populate_raw_post_data = On,PHP 5.6+ 棄用)
    $content = $GLOBALS['HTTP_RAW_POST_DATA'] ?? '';

    // 2. 回退到 php://input(不依賴 ini 配置,內存壓力較小,推薦)
    if (empty($content)) {
        $content = file_get_contents('php://input');
    }

    // 3. 寫入文件(FILE_APPEND 防止多次調用覆蓋,通常用 LOCK_EX 獨佔鎖)
    $bytes = @file_put_contents($file, $content, LOCK_EX);
    return $bytes !== false ? $bytes : false;
}

// 使用示例:接收客戶端 POST 的圖片二進制流
binary_to_file('uploads/photo_' . time() . '.png');

關鍵差異對比

特性$GLOBALS['HTTP_RAW_POST_DATA']php://input
PHP 版本要求所有版本(PHP 5.6+ 棄用,7.0+ 移除)PHP 4.3+
需配置 php.ini是(always_populate_raw_post_data = On)否
內存佔用始終佔用內存緩存整個請求體流式讀取,可配合 fopen('php://input', 'r') 分塊處理大文件
multipart/form-data 支援不支援不支援

⚠️ 重要限制

  • 不適用於 enctype="multipart/form-data" 的表單上傳。該場景請使用 $_FILES 超全局變量。
  • 若同時啟用 always_populate_raw_post_data 並嘗試讀取 php://input,PHP 5.6+ 會報 Deprecated 警告。
  • 大文件上傳建議使用分塊讀取:$fp = fopen('php://input', 'r'); while(!feof($fp)) { fwrite($dst, fread($fp, 8192)); }。

典型應用場景

  1. 微信/支付寶回調通知:XML/JSON 原始體驗證簽名。
  2. 物聯網設備上報:二進制協議數據直接落盤解析。
  3. API 网關透傳:接收上游服務轉發的原始請求體。
  4. Webhook 接收器:GitHub、GitLab 等推送的 JSON Payload。

安全建議

  • 驗證 Content-Type、Content-Length、來源 IP 白名單、簽名/Token 驗證。
  • 限制最大文件大小:ini_set('memory_limit', '64M'); 或 Nginx client_max_body_size 10M;。
  • 文件名隨機化存儲,執行權限隔離(上傳目錄禁用腳本執行)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved