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

PHP JSON 處理完全指南:json_encode/decode 深度解析與避坑指南

     編輯:PHP 相關知識

自 PHP 5.2 起內建 json_encode() / json_decode(),成為前後端數據交換、API 序列化、配置存儲的標準工具。但編碼限制、類型映射、錯誤處理等細節常被忽視。本文系統梳理核心用法、陷阱與最佳實踐。

json_encode():PHP 值 → JSON 字符串

基礎類型映射

PHP 類型JSON 類型示例
array (索引數組,鍵為 0..n 連續整數)Array []['a','b'] → ["a","b"]
array (關聯數組/非連續鍵)Object {}[1=>'a',3=>'b'] → {"1":"a","3":"b"}
object (stdClass/自定義類)Object {}僅編碼 **public** 屬性
null / true / false / int / floatnull / true / false / number直接映射
resource—編碼為 null 並拋警告

關鍵選項常量

json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK);
// JSON_UNESCAPED_UNICODE: 中文不轉 \uXXXX,可讀性↑、體積↓
// JSON_UNESCAPED_SLASHES: / 不轉 \/,URL 路徑更清爽
// JSON_NUMERIC_CHECK: 數值字符串 "123" 強制編碼為數字 123(謹慎用,可能改變語義)
// JSON_PRESERVE_ZERO_FRACTION: 1.0 保留 .0
// JSON_THROW_ON_ERROR: PHP 7.3+ 失敗拋 JsonException,替代 json_last_error()

強制索引數組編碼為對象

json_encode(['a','b'], JSON_FORCE_OBJECT); // {"0":"a","1":"b"}
json_encode((object)['a','b']); // 同上

類編碼限制

class User {
    public $name = 'Tom';
    private $password = 'secret'; // 不會被編碼
    protected $role = 'admin';    // 不會被編碼
    const TYPE = 'member';        // 不會被編碼
    public function greet() {}    // 方法不編碼
}
echo json_encode(new User()); // {"name":"Tom"}

需完整序列化對象(含私有屬性),實現 JsonSerializable 接口:

class User implements JsonSerializable {
    private $password;
    public function jsonSerialize(): array {
        return ['name' => $this->name, 'role' => $this->role]; // 自定義輸出
    }
}

json_decode():JSON 字符串 → PHP 值

核心參數

json_decode(string $json, bool $associative = false, int $depth = 512, int $flags = 0): mixed
  • $associative = true:返回**關聯數組**而非 stdClass 對象(推薦統一用數組,便於數組函數處理)。
  • $depth:最大遞歸深度,防止惡意深層嵌套導致棧溢出。
  • $flags:JSON_BIGINT_AS_STRING 將超出 PHP 整數範圍的數字解析為字符串(避免精度丟失);JSON_THROW_ON_ERROR 同編碼端。

常見錯誤 JSON 寫法(均導致解析失敗返回 null)

  1. 單引號包裹鍵/值:{'foo':'bar'} ❌ → 必須雙引號 {"foo":"bar"}。
  2. 鍵名無引號:{foo:"bar"} ❌。
  3. 尾隨逗號:{"a":1,} ❌(JSON 不允許,JS 對象字面量允許)。
  4. 註釋:{/*comment*/"a":1} ❌(標準 JSON 無註釋,需預處理移除)。

編碼陷阱:UTF-8 強制要求

json_encode() **要求輸入為 UTF-8 編碼**;非 UTF-8(如 GBK、Latin1)會導致字符變為 null 或空字符串。解決:

$data = ['msg' => '中文'];
// 若源數據為 GBK
$data['msg'] = mb_convert_encoding($data['msg'], 'UTF-8', 'GBK');
echo json_encode($data, JSON_UNESCAPED_UNICODE);

錯誤處理最佳實踐 (PHP 7.3+)

try {
    $arr = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
    // 記錄 $e->getMessage()、$json 片段、請求上下文
    throw new ApiException('Invalid JSON payload', 400, $e);
}

性能與替代方案

  • 極大數據(>10MB)編解碼較慢,考慮 igbinary、msgpack 二進制序列化(需擴展)。
  • 高頻 API 可用 json_encode 緩存結果(Key 含數據版本號)。
  • 流式解析大 JSON 文件:halaxa/json-stream、salsify/json-streaming-parser。

規範使用 JSON 選項、統一關聯數組模式、嚴格異常處理、編碼預檢,能消除 90% 以上線上 JSON 相關故障。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved