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

PHP 接收 POST 數據並解析 JSON 完整指南:魔術引號兼容與錯誤處理

     編輯:PHP 相關知識

現代 API 多以 `Content-Type: application/json` 發送數據,PHP `$_POST` **不會自動解析 JSON Body**,需讀取 `php://input` 或處理傳統表單字段中的 JSON 字符串。本文涵蓋兩種接收方式、魔術引號兼容、錯誤處理、安全建議。

場景一:表單字段傳 JSON 字符串 (傳統兼容)

<?php
// 前端: 
$jsonString = $_POST['txt_json'] ?? '';

// 兼容魔術引號 (PHP < 5.4 已移除,舊項目可能仍開啟)
if (ini_get('magic_quotes_gpc') === '1') {
    $jsonString = stripslashes($jsonString);
}

$data = json_decode($jsonString, true); // 關鍵:第二參數 true 返回關聯數組

if (json_last_error() !== JSON_ERROR_NONE) {
    die('JSON 解析失敗: ' . json_last_error_msg());
}

var_dump($data); // ['name' => 'Tom', 'age' => 18]
?>

場景二:標準 JSON API (推薦) — 讀取 php://input

<?php
// Content-Type: application/json
// Body: {"name":"Tom","age":18}

$raw = file_get_contents('php://input'); // 獲取原始請求體
if (empty($raw)) {
    die('請求體為空');
}

$data = json_decode($raw, true);
if (json_last_error() !== JSON_ERROR_NONE) {
    http_response_code(400);
    die('JSON 解析錯誤: ' . json_last_error_msg());
}

// 業務邏輯
echo json_encode(['status' => 'ok', 'received' => $data]);
?>

關鍵差異對比

特性$_POST['field']php://input
適用 Content-Typeapplication/x-www-form-urlencoded, multipart/form-data**任意** (application/json, text/xml, 等)
自動解析是 (PHP 內置)否 (需手動 json_decode/xml_parse)
可讀性多次讀取安全**只能讀取一次** (流),需變量保存
魔術引號影響受 `magic_quotes_gpc` 影響不受影響
大文件上傳受 `post_max_size` 限制同,但可配合流式處理

通用封裝函數 (兼容兩種場景)

<?php
function getJsonInput(): array {
    // 1. 嘗試 php://input (標準 API)
    $raw = file_get_contents('php://input');
    if (!empty($raw)) {
        $data = json_decode($raw, true);
        if (json_last_error() === JSON_ERROR_NONE) return $data;
    }

    // 2. 回退:表單字段 txt_json (兼容舊前端)
    $jsonStr = $_POST['txt_json'] ?? '';
    if ($jsonStr !== '') {
        if (ini_get('magic_quotes_gpc') === '1') {
            $jsonStr = stripslashes($jsonStr);
        }
        $data = json_decode($jsonStr, true);
        if (json_last_error() === JSON_ERROR_NONE) return $data;
    }

    // 3. 失敗
    http_response_code(400);
    die(json_encode(['error' => 'Invalid JSON input', 'code' => 400]));
}

// 使用
$data = getJsonInput();
// $data 保證是關聯數組
?>

安全與健壯性清單

  • ✅ **始終用 `json_decode($str, true)`** 返回陣列,避免 `stdClass` 對象屬性訪問差異。
  • ✅ **檢查 `json_last_error()`** 捕獲語法錯誤、UTF-8 非法序列、深度超限等。
  • ✅ **限制請求體大小**:`ini_set('post_max_size', '2M')` / Nginx `client_max_body_size` / `$_SERVER['CONTENT_LENGTH']` 檢查。
  • ✅ **驗證 Content-Type**:`if (strpos($_SERVER['CONTENT_TYPE'] ?? '', 'application/json') !== 0) { /* 拒絕或警告 */ }`
  • ✅ **輸入驗證**:解析後對 `$data` 進行結構/類型/範圍驗證 (可用 `respect/validation`、`laminas/validator`)。
  • ⚠️ **魔術引號** `magic_quotes_gpc` 已在 PHP 5.4 移除,現代項目無需兼容,但舊項目保留 `stripslashes` 無害。

常見錯誤代碼速查

常量值含義
JSON_ERROR_NONE0無錯誤
JSON_ERROR_DEPTH1嵌套深度超限 (默認 512)
JSON_ERROR_STATE_MISMATCH2狀態不匹配 (編碼器邏輯錯)
JSON_ERROR_CTRL_CHAR3控制字符錯誤 (未轉義)
JSON_ERROR_SYNTAX4語法錯誤 (最常見)
JSON_ERROR_UTF85非法 UTF-8 序列
JSON_ERROR_RECURSION6遞歸引用 (編碼時)
JSON_ERROR_INF_OR_NAN7Inf/NaN 數值 (編碼時)
JSON_ERROR_UNSUPPORTED_TYPE8不支持類型 (如 resource)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved