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

PHP 數組轉 JSON:原生 json_encode 完勝手寫遞歸,附兼容舊版本 Polyfill 方案

     編輯:PHP 相關知識

核心結論

**PHP 5.2.0+ 內置 json_encode() / json_decode() 是標準、高性能、安全的解決方案**。本文原示例的手寫遞歸函數 array_to_json 存在嚴重缺陷:**不支持 Unicode 轉義、浮點數精度丟失、無法處理資源/對象、JSON 格式不嚴格 (單引號、尾逗號風險)**。生產環境**嚴禁**使用手寫實現。

正確用法:json_encode

<?php
$data = [
    'id' => 1001,
    'name' => '張三',
    'tags' => ['vip', 'active'],
    'score' => 98.5,
    'metadata' => (object)['source' => 'web', 'version' => 2],
    'created_at' => new DateTime('2024-01-01'),
];

// 基礎輸出
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
/* {"id":1001,"name":"張三","tags":["vip","active"],"score":98.5,"metadata":{"source":"web","version":2},"created_at":"2024-01-01 00:00:00"} */

// 美化輸出 (調試/日誌)
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);

/* {
    "id": 1001,
    "name": "張三",
    "tags": ["vip", "active"],
    "score": 98.5,
    "metadata": {"source": "web", "version": 2},
    "created_at": "2024-01-01 00:00:00"
} */
?>

常用選項位掩碼

常量作用
JSON_UNESCAPED_UNICODE中文不轉 \uXXXX,直接輸出 UTF-8 (節省體積、可讀)
JSON_UNESCAPED_SLASHES不轉義 / (前端模板常需)
JSON_PRETTY_PRINT縮進換行格式化
JSON_NUMERIC_CHECK數字字符串 "123" → 123 (謹慎用,可能改變語義)
JSON_PRESERVE_ZERO_FRACTION1.0 保持為 1.0 不變 1
JSON_FORCE_OBJECT索引數組強制輸出為對象 {}
JSON_THROW_ON_ERRORPHP 7.3+ 編碼失敗拋出異常 (而非返回 false)

處理特殊類型:實現 JsonSerializable

<?php
class User implements JsonSerializable {
    private $id, $name, $password; // 密碼不應序列化

    public function __construct(int $id, string $name, string $pwd) {
        $this->id = $id; $this->name = $name; $this->password = $pwd;
    }

    public function jsonSerialize(): array {
        return [
            'id' => $this->id,
            'name' => $this->name,
            // password 故意省略
        ];
    }
}

$user = new User(1, 'Admin', 'secret123');
echo json_encode($user, JSON_UNESCAPED_UNICODE); // {"id":1,"name":"Admin"}
?>

極舊環境 (PHP < 5.2) Polyfill 方案

若必須在 PHP 5.1 或更老版本運行 (極罕見),請使用 **PECL JSON 擴展** 或引入 **Services_JSON** (PEAR 庫):**切勿複製手寫遞歸代碼**。

// composer require pear/services_json
require 'vendor/autoload.php';
$json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
echo $json->encode($data);

手寫 array_to_json 的具體缺陷分析

缺陷示例後果
單引號非標準'name': 'value'標準 JSON 必須雙引號,前端 JSON.parse 失敗
無 Unicode 轉義中文直接輸出或亂碼非 UTF-8 環境解析錯誤,體積膨脹
浮點數截斷98.5000000001 → 98.5精度丟失,金額計算災難
無法處理對象/資源new DateTime(), fopen()報錯或輸出空值
遞歸深度無限制循環引用 $a['self']=&$a無限遞歸導致棧溢出
尾逗號風險{"a":1,}非標準 JSON,解析器拒絕

總結

**永遠使用 json_encode()**。它是 C 實現、經過億級生產驗證、符合 RFC 8259 標準、支持所有 PHP 類型 (配合 JsonSerializable)、性能極高。手寫 JSON 編碼器是「重複造輪子」且「造出方輪子」的典型反面教材。

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