JSON 在 PHP 中的使用

JSON 与 PHP

PHP 内置了强大的 JSON 处理函数,可以轻松地在 JSON 数据和 PHP 数组/对象之间进行转换。PHP 5.2.0 及以上版本原生支持 JSON。

{"{}"}

json_decode()

将 JSON 字符串转换为 PHP 变量

" "

json_encode()

将 PHP 变量转换为 JSON 字符串

📁

文件操作

读写 JSON 文件

🔧

高级功能

错误处理、选项配置

JSON 解析 - json_decode()

json_decode() 函数用于将 JSON 字符串解析为 PHP 变量。

基本使用

<?php
// JSON 字符串
$jsonString = '{"name": "张三", "age": 30, "isStudent": false}';

// 解析为 PHP 关联数组
$data = json_decode($jsonString, true);

echo "姓名: " . $data['name'] . "\n";      // 张三
echo "年龄: " . $data['age'] . "\n";       // 30
echo "是否学生: " . ($data['isStudent'] ? '是' : '否') . "\n"; // 否

// 检查数据类型
echo "数据类型: " . gettype($data) . "\n"; // array
?>

解析为对象

<?php
// JSON 字符串
$jsonString = '{"name": "李四", "age": 25, "isStudent": true}';

// 解析为 PHP 对象(默认行为)
$data = json_decode($jsonString);

echo "姓名: " . $data->name . "\n";        // 李四
echo "年龄: " . $data->age . "\n";         // 25
echo "是否学生: " . ($data->isStudent ? '是' : '否') . "\n"; // 是

// 检查数据类型
echo "数据类型: " . gettype($data) . "\n"; // object
echo "对象类: " . get_class($data) . "\n"; // stdClass
?>

处理复杂 JSON 数据

<?php
// 复杂的 JSON 字符串
$complexJson = '{
  "users": [
    {
      "id": 1,
      "name": "张三",
      "hobbies": ["阅读", "游泳"],
      "profile": {
        "age": 30,
        "city": "北京"
      }
    },
    {
      "id": 2,
      "name": "李四",
      "hobbies": ["音乐", "旅行"],
      "profile": {
        "age": 25,
        "city": "上海"
      }
    }
  ]
}';

// 解析为关联数组
$data = json_decode($complexJson, true);

// 访问嵌套数据
echo "第一个用户: " . $data['users'][0]['name'] . "\n";                    // 张三
echo "第一个用户的第一个爱好: " . $data['users'][0]['hobbies'][0] . "\n";   // 阅读
echo "第二个用户的城市: " . $data['users'][1]['profile']['city'] . "\n";   // 上海

// 遍历用户数据
foreach ($data['users'] as $user) {
    echo "用户: " . $user['name'] . ", 年龄: " . $user['profile']['age'] . "\n";
    echo "爱好: " . implode(', ', $user['hobbies']) . "\n\n";
}
?>

JSON 序列化 - json_encode()

json_encode() 函数用于将 PHP 变量序列化为 JSON 字符串。

基本使用

<?php
// PHP 数组
$data = [
    "name" => "张三",
    "age" => 30,
    "isStudent" => false,
    "hobbies" => ["阅读", "游泳"]
];

// 序列化为 JSON 字符串
$jsonString = json_encode($data);

echo $jsonString . "\n";
// 输出: {"name":"张三","age":30,"isStudent":false,"hobbies":["阅读","游泳"]}

// 美化输出
$prettyJson = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
echo $prettyJson . "\n";
/* 输出:
{
    "name": "张三",
    "age": 30,
    "isStudent": false,
    "hobbies": [
        "阅读",
        "游泳"
    ]
}
*/
?>

处理中文和特殊字符

<?php
$data = [
    "name" => "张三",
    "city" => "北京",
    "description" => "这是一个包含中文和\"引号\"的字符串"
];

// 默认输出(中文被编码)
$default = json_encode($data);
echo "默认: " . $default . "\n";
// 输出: {"name":"\u5f20\u4e09","city":"\u5317\u4eac","description":"这是一个包含中文和\"引号\"的字符串"}

// 保留中文字符
$chinese = json_encode($data, JSON_UNESCAPED_UNICODE);
echo "保留中文: " . $chinese . "\n";
// 输出: {"name":"张三","city":"北京","description":"这是一个包含中文和\"引号\"的字符串"}

// 保留中文字符并美化
$prettyChinese = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
echo "美化中文:\n" . $prettyChinese . "\n";
?>

序列化对象

<?php
// 创建 PHP 对象
class User {
    public $name;
    public $age;
    private $password; // 私有属性默认不会被序列化

    public function __construct($name, $age, $password) {
        $this->name = $name;
        $this->age = $age;
        $this->password = $password;
    }

    // 可以通过实现 JsonSerializable 接口自定义序列化
    public function jsonSerialize() {
        return [
            'name' => $this->name,
            'age' => $this->age,
            'type' => 'user'
        ];
    }
}

$user = new User("王五", 35, "secret123");

// 序列化对象
$userJson = json_encode($user, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
echo "对象JSON:\n" . $userJson . "\n";
/* 输出:
{
    "name": "王五",
    "age": 35,
    "type": "user"
}
*/

// 使用 JsonSerializable 接口
class CustomUser implements JsonSerializable {
    private $data;

    public function __construct($name, $email) {
        $this->data = [
            'name' => $name,
            'email' => $email,
            'created_at' => date('Y-m-d H:i:s')
        ];
    }

    public function jsonSerialize() {
        return $this->data;
    }
}

$customUser = new CustomUser("赵六", "zhaoliu@example.com");
$customJson = json_encode($customUser, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
echo "自定义序列化:\n" . $customJson . "\n";
?>

JSON 选项常量

PHP 提供了多个 JSON 选项常量来控制编码和解码行为。

编码选项

<?php
$data = [
    "name" => "张三",
    "age" => 30,
    "city" => "北京",
    "special" => "包含\"引号\"和/斜线",
    "empty" => null
];

echo "默认: " . json_encode($data) . "\n\n";

// 常用选项组合
$options = JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
echo "美化 + 中文 + 不转义斜线:\n" . json_encode($data, $options) . "\n\n";

// 数值检查
$numericData = ["123", 123, 12.3, "12.3"];
echo "数值检查前: " . json_encode($numericData) . "\n";
echo "数值检查后: " . json_encode($numericData, JSON_NUMERIC_CHECK) . "\n\n";

// 强制对象
$arrayData = ["a", "b", "c"];
echo "数组: " . json_encode($arrayData) . "\n";
echo "强制对象: " . json_encode($arrayData, JSON_FORCE_OBJECT) . "\n";
?>

解码选项

<?php
$jsonString = '{"name": "张三", "age": 30, "city": "北京"}';

// 默认解码为对象
$obj = json_decode($jsonString);
echo "对象访问: " . $obj->name . "\n";

// 解码为关联数组
$arr = json_decode($jsonString, true);
echo "数组访问: " . $arr['name'] . "\n";

// 大整数处理
$bigIntJson = '{"big_number": 12345678901234567890}';
$bigIntData = json_decode($bigIntJson, true);
echo "大整数默认: " . $bigIntData['big_number'] . " (类型: " . gettype($bigIntData['big_number']) . ")\n";

// 大整数作为字符串
$bigIntAsString = json_decode($bigIntJson, true, 512, JSON_BIGINT_AS_STRING);
echo "大整数作为字符串: " . $bigIntAsString['big_number'] . " (类型: " . gettype($bigIntAsString['big_number']) . ")\n";
?>

常用选项常量

选项常量 描述 适用函数
JSON_PRETTY_PRINT 美化输出,使用空格和换行格式化 json_encode()
JSON_UNESCAPED_UNICODE 不转义 Unicode 字符 json_encode()
JSON_UNESCAPED_SLASHES 不转义斜线 json_encode()
JSON_NUMERIC_CHECK 将数字字符串转换为数字 json_encode()
JSON_FORCE_OBJECT 将数组强制转换为对象 json_encode()
JSON_BIGINT_AS_STRING 将大整数作为字符串处理 json_decode()
JSON_THROW_ON_ERROR 错误时抛出异常(PHP 7.3+) json_encode()/json_decode()

JSON 文件操作

PHP 可以轻松地读写 JSON 文件。

读取 JSON 文件

<?php
// 读取 JSON 文件
function readJsonFile($filename) {
    if (!file_exists($filename)) {
        return null;
    }

    $jsonString = file_get_contents($filename);
    if ($jsonString === false) {
        return null;
    }

    return json_decode($jsonString, true);
}

// 使用示例
$data = readJsonFile('config.json');
if ($data) {
    echo "配置文件内容:\n";
    print_r($data);
} else {
    echo "文件不存在或读取失败\n";
}
?>

写入 JSON 文件

<?php
// 写入 JSON 文件
function writeJsonFile($filename, $data) {
    $jsonString = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
    if ($jsonString === false) {
        return false;
    }

    return file_put_contents($filename, $jsonString) !== false;
}

// 使用示例
$userData = [
    "users" => [
        [
            "id" => 1,
            "name" => "张三",
            "email" => "zhangsan@example.com"
        ],
        [
            "id" => 2,
            "name" => "李四",
            "email" => "lisi@example.com"
        ]
    ]
];

if (writeJsonFile('users.json', $userData)) {
    echo "数据已保存到 users.json\n";
} else {
    echo "保存失败\n";
}
?>

完整的配置文件管理

<?php
class ConfigManager {
    private $configFile;
    private $data;

    public function __construct($configFile = 'config.json') {
        $this->configFile = $configFile;
        $this->data = $this->loadConfig();
    }

    private function loadConfig() {
        if (!file_exists($this->configFile)) {
            // 创建默认配置
            $defaultConfig = [
                "database" => [
                    "host" => "localhost",
                    "port" => 3306,
                    "name" => "myapp"
                ],
                "app" => [
                    "debug" => true,
                    "version" => "1.0.0"
                ]
            ];
            $this->saveConfig($defaultConfig);
            return $defaultConfig;
        }

        $jsonString = file_get_contents($this->configFile);
        if ($jsonString === false) {
            throw new Exception("无法读取配置文件: " . $this->configFile);
        }

        $data = json_decode($jsonString, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new Exception("配置文件格式错误: " . json_last_error_msg());
        }

        return $data;
    }

    public function saveConfig($data = null) {
        if ($data === null) {
            $data = $this->data;
        }

        $jsonString = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
        if ($jsonString === false) {
            throw new Exception("JSON 编码失败: " . json_last_error_msg());
        }

        if (file_put_contents($this->configFile, $jsonString) === false) {
            throw new Exception("无法写入配置文件: " . $this->configFile);
        }

        $this->data = $data;
        return true;
    }

    public function get($key, $default = null) {
        $keys = explode('.', $key);
        $value = $this->data;

        foreach ($keys as $k) {
            if (!isset($value[$k])) {
                return $default;
            }
            $value = $value[$k];
        }

        return $value;
    }

    public function set($key, $value) {
        $keys = explode('.', $key);
        $data = &$this->data;

        foreach ($keys as $k) {
            if (!isset($data[$k]) || !is_array($data[$k])) {
                $data[$k] = [];
            }
            $data = &$data[$k];
        }

        $data = $value;
        return $this->saveConfig();
    }
}

// 使用示例
try {
    $config = new ConfigManager();

    echo "数据库主机: " . $config->get('database.host') . "\n";
    echo "应用调试模式: " . ($config->get('app.debug') ? '开启' : '关闭') . "\n";

    // 修改配置
    $config->set('app.debug', false);
    $config->set('database.port', 5432);

    echo "配置已更新\n";

} catch (Exception $e) {
    echo "错误: " . $e->getMessage() . "\n";
}
?>

错误处理

正确处理 JSON 编码和解码过程中的错误非常重要。

基本的错误处理

<?php
// 检查 JSON 操作是否成功
function safeJsonDecode($jsonString, $assoc = true) {
    $data = json_decode($jsonString, $assoc);

    if (json_last_error() !== JSON_ERROR_NONE) {
        throw new Exception('JSON 解码错误: ' . json_last_error_msg());
    }

    return $data;
}

function safeJsonEncode($data, $options = 0) {
    $jsonString = json_encode($data, $options);

    if ($jsonString === false) {
        throw new Exception('JSON 编码错误: ' . json_last_error_msg());
    }

    return $jsonString;
}

// 使用示例
try {
    // 有效的 JSON
    $validJson = '{"name": "张三", "age": 30}';
    $data = safeJsonDecode($validJson);
    echo "解析成功: " . $data['name'] . "\n";

    // 无效的 JSON
    $invalidJson = '{"name": "张三", "age": 30,}'; // 多余的逗号
    $data = safeJsonDecode($invalidJson);

} catch (Exception $e) {
    echo "捕获异常: " . $e->getMessage() . "\n";
}

// 使用 JSON_THROW_ON_ERROR (PHP 7.3+)
try {
    $data = ['name' => '张三', 'age' => 30];
    $json = json_encode($data, JSON_THROW_ON_ERROR);
    echo "编码成功: " . $json . "\n";

    // 深度嵌套可能导致错误
    $deepData = [];
    $current = &$deepData;
    for ($i = 0; $i < 1000; $i++) {
        $current['level'] = $i;
        $current['next'] = [];
        $current = &$current['next'];
    }
    $json = json_encode($deepData, JSON_THROW_ON_ERROR);

} catch (JsonException $e) {
    echo "JSON 异常: " . $e->getMessage() . "\n";
}
?>

JSON 错误常量

错误常量 描述 可能的原因
JSON_ERROR_NONE 没有错误 -
JSON_ERROR_DEPTH 达到了最大堆栈深度 数据结构嵌套太深
JSON_ERROR_STATE_MISMATCH 无效或异常的 JSON JSON 格式错误
JSON_ERROR_CTRL_CHAR 控制字符错误 包含无效的控制字符
JSON_ERROR_SYNTAX 语法错误 JSON 格式不正确
JSON_ERROR_UTF8 畸形的 UTF-8 字符 包含无效的 UTF-8 字符
JSON_ERROR_RECURSION 递归引用 对象或数组包含递归引用
JSON_ERROR_INF_OR_NAN NAN 或 INF 包含 NAN 或 INF 值
JSON_ERROR_UNSUPPORTED_TYPE 不支持的类型 包含无法编码的值类型

错误处理函数

<?php
function getJsonErrorDetails() {
    $errorCode = json_last_error();
    $errorMsg = json_last_error_msg();

    $errorTypes = [
        JSON_ERROR_NONE => '没有错误',
        JSON_ERROR_DEPTH => '达到了最大堆栈深度',
        JSON_ERROR_STATE_MISMATCH => '无效或异常的 JSON',
        JSON_ERROR_CTRL_CHAR => '控制字符错误',
        JSON_ERROR_SYNTAX => '语法错误',
        JSON_ERROR_UTF8 => '畸形的 UTF-8 字符',
        JSON_ERROR_RECURSION => '递归引用',
        JSON_ERROR_INF_OR_NAN => 'NAN 或 INF',
        JSON_ERROR_UNSUPPORTED_TYPE => '不支持的类型'
    ];

    return [
        'code' => $errorCode,
        'message' => $errorMsg,
        'description' => $errorTypes[$errorCode] ?? '未知错误'
    ];
}

// 使用示例
$invalidJson = '{"name": "张三", "age": }'; // 缺少值
$data = json_decode($invalidJson);

$errorDetails = getJsonErrorDetails();
echo "错误代码: " . $errorDetails['code'] . "\n";
echo "错误信息: " . $errorDetails['message'] . "\n";
echo "错误描述: " . $errorDetails['description'] . "\n";
?>

实际应用场景

1. API 开发

<?php
// 简单的 API 响应类
class ApiResponse {
    public static function success($data = null, $message = '成功') {
        return self::json([
            'success' => true,
            'message' => $message,
            'data' => $data,
            'timestamp' => time()
        ]);
    }

    public static function error($message = '错误', $code = 400, $data = null) {
        http_response_code($code);
        return self::json([
            'success' => false,
            'message' => $message,
            'data' => $data,
            'timestamp' => time()
        ]);
    }

    private static function json($data) {
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
        exit;
    }
}

// 模拟用户数据
$users = [
    ['id' => 1, 'name' => '张三', 'email' => 'zhangsan@example.com'],
    ['id' => 2, 'name' => '李四', 'email' => 'lisi@example.com']
];

// 处理 GET 请求 - 获取用户列表
if ($_SERVER['REQUEST_METHOD'] === 'GET' && $_SERVER['REQUEST_URI'] === '/api/users') {
    ApiResponse::success($users, '用户列表获取成功');
}

// 处理 POST 请求 - 创建用户
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $_SERVER['REQUEST_URI'] === '/api/users') {
    $input = json_decode(file_get_contents('php://input'), true);

    if (!isset($input['name']) || !isset($input['email'])) {
        ApiResponse::error('缺少必要参数', 400);
    }

    $newUser = [
        'id' => count($users) + 1,
        'name' => $input['name'],
        'email' => $input['email']
    ];
    $users[] = $newUser;

    ApiResponse::success($newUser, '用户创建成功', 201);
}

// 如果没有匹配的路由
ApiResponse::error('接口不存在', 404);
?>

2. 数据导入导出

<?php
class DataExporter {

    // 导出数据到 JSON 文件
    public static function exportToFile($data, $filename) {
        $json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);

        if (file_put_contents($filename, $json) === false) {
            throw new Exception("无法写入文件: $filename");
        }

        return true;
    }

    // 从 JSON 文件导入数据
    public static function importFromFile($filename) {
        if (!file_exists($filename)) {
            throw new Exception("文件不存在: $filename");
        }

        $json = file_get_contents($filename);
        if ($json === false) {
            throw new Exception("无法读取文件: $filename");
        }

        $data = json_decode($json, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new Exception("JSON 解析错误: " . json_last_error_msg());
        }

        return $data;
    }

    // 导出为下载文件
    public static function exportDownload($data, $filename = 'data.json') {
        $json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);

        header('Content-Type: application/json');
        header('Content-Disposition: attachment; filename="' . $filename . '"');
        header('Content-Length: ' . strlen($json));

        echo $json;
        exit;
    }
}

// 使用示例
$products = [
    ['id' => 1, 'name' => '笔记本电脑', 'price' => 5999, 'category' => '电子产品'],
    ['id' => 2, 'name' => '智能手机', 'price' => 2999, 'category' => '电子产品'],
    ['id' => 3, 'name' => '办公椅', 'price' => 899, 'category' => '家具']
];

try {
    // 导出到文件
    DataExporter::exportToFile($products, 'products.json');
    echo "数据已导出到 products.json\n";

    // 从文件导入
    $importedData = DataExporter::importFromFile('products.json');
    echo "成功导入 " . count($importedData) . " 条记录\n";

    // 在 Web 环境中,可以这样提供下载:
    // DataExporter::exportDownload($products, 'products_export.json');

} catch (Exception $e) {
    echo "错误: " . $e->getMessage() . "\n";
}
?>

3. 配置管理和缓存

<?php
class JsonCache {
    private $cacheDir;

    public function __construct($cacheDir = 'cache') {
        $this->cacheDir = $cacheDir;
        if (!is_dir($this->cacheDir)) {
            mkdir($this->cacheDir, 0755, true);
        }
    }

    // 设置缓存
    public function set($key, $data, $ttl = 3600) {
        $cacheFile = $this->getCacheFile($key);
        $cacheData = [
            'data' => $data,
            'expires' => time() + $ttl,
            'created' => time()
        ];

        $json = json_encode($cacheData, JSON_UNESCAPED_UNICODE);
        return file_put_contents($cacheFile, $json) !== false;
    }

    // 获取缓存
    public function get($key) {
        $cacheFile = $this->getCacheFile($key);

        if (!file_exists($cacheFile)) {
            return null;
        }

        $json = file_get_contents($cacheFile);
        $cacheData = json_decode($json, true);

        if ($cacheData === null) {
            // JSON 解析失败,删除损坏的缓存文件
            unlink($cacheFile);
            return null;
        }

        // 检查是否过期
        if (time() > $cacheData['expires']) {
            unlink($cacheFile);
            return null;
        }

        return $cacheData['data'];
    }

    // 删除缓存
    public function delete($key) {
        $cacheFile = $this->getCacheFile($key);
        if (file_exists($cacheFile)) {
            return unlink($cacheFile);
        }
        return true;
    }

    // 清空所有缓存
    public function clear() {
        $files = glob($this->cacheDir . '/*.json');
        foreach ($files as $file) {
            if (is_file($file)) {
                unlink($file);
            }
        }
        return true;
    }

    private function getCacheFile($key) {
        $safeKey = preg_replace('/[^a-zA-Z0-9_-]/', '_', $key);
        return $this->cacheDir . '/' . $safeKey . '.json';
    }
}

// 使用示例
$cache = new JsonCache();

// 模拟昂贵的操作
function expensiveOperation($param) {
    sleep(2); // 模拟耗时操作
    return "处理结果: $param - " . date('Y-m-d H:i:s');
}

$param = 'test_data';

// 尝试从缓存获取
$result = $cache->get($param);
if ($result === null) {
    echo "缓存未命中,执行昂贵操作...\n";
    $result = expensiveOperation($param);
    $cache->set($param, $result, 60); // 缓存60秒
    echo "结果已缓存\n";
} else {
    echo "缓存命中!\n";
}

echo "结果: " . $result . "\n";
?>

最佳实践

1. 统一的 JSON 处理函数

<?php
class JsonHelper {

    // 安全的 JSON 解码
    public static function decode($jsonString, $assoc = true) {
        if (empty($jsonString)) {
            return $assoc ? [] : null;
        }

        $data = json_decode($jsonString, $assoc);

        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new InvalidArgumentException(
                'JSON 解码错误: ' . json_last_error_msg() .
                ' - 原始字符串: ' . substr($jsonString, 0, 100)
            );
        }

        return $data;
    }

    // 安全的 JSON 编码
    public static function encode($data, $options = null) {
        if ($options === null) {
            $options = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
        }

        $jsonString = json_encode($data, $options);

        if ($jsonString === false) {
            throw new RuntimeException(
                'JSON 编码错误: ' . json_last_error_msg() .
                ' - 数据类型: ' . gettype($data)
            );
        }

        return $jsonString;
    }

    // 美化 JSON 输出
    public static function prettyEncode($data) {
        return self::encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    }

    // 验证 JSON 字符串
    public static function isValid($jsonString) {
        if (empty($jsonString)) {
            return false;
        }

        json_decode($jsonString);
        return json_last_error() === JSON_ERROR_NONE;
    }
}

// 使用示例
try {
    $data = ['name' => '张三', 'skills' => ['PHP', 'JavaScript']];

    $json = JsonHelper::encode($data);
    echo "编码结果: " . $json . "\n";

    $prettyJson = JsonHelper::prettyEncode($data);
    echo "美化结果:\n" . $prettyJson . "\n";

    $decoded = JsonHelper::decode($json);
    echo "解码后的姓名: " . $decoded['name'] . "\n";

    echo "JSON 验证: " . (JsonHelper::isValid($json) ? '有效' : '无效') . "\n";
    echo "无效 JSON 验证: " . (JsonHelper::isValid('{invalid}') ? '有效' : '无效') . "\n";

} catch (Exception $e) {
    echo "错误: " . $e->getMessage() . "\n";
}
?>

2. 处理特殊数据类型

<?php
class AdvancedJsonHelper {

    // 处理包含 DateTime 的对象
    public static function encodeWithDates($data) {
        $processedData = self::processDataForEncoding($data);
        return json_encode($processedData, JSON_UNESCAPED_UNICODE);
    }

    private static function processDataForEncoding($data) {
        if (is_array($data)) {
            return array_map([self::class, 'processDataForEncoding'], $data);
        }

        if (is_object($data)) {
            if ($data instanceof DateTime) {
                return $data->format('Y-m-d H:i:s');
            }

            if (method_exists($data, 'toArray')) {
                return self::processDataForEncoding($data->toArray());
            }

            if (method_exists($data, 'jsonSerialize')) {
                return self::processDataForEncoding($data->jsonSerialize());
            }

            return self::processDataForEncoding((array) $data);
        }

        return $data;
    }

    // 从 JSON 重建 DateTime 对象
    public static function decodeWithDates($jsonString, $dateFields = []) {
        $data = json_decode($jsonString, true);

        if ($data === null) {
            throw new InvalidArgumentException('JSON 解码失败');
        }

        return self::processDataAfterDecoding($data, $dateFields);
    }

    private static function processDataAfterDecoding($data, $dateFields) {
        if (is_array($data)) {
            foreach ($data as $key => &$value) {
                if (is_array($value)) {
                    $value = self::processDataAfterDecoding($value, $dateFields);
                } elseif (is_string($value) && in_array($key, $dateFields)) {
                    // 尝试解析为 DateTime
                    try {
                        $value = new DateTime($value);
                    } catch (Exception $e) {
                        // 保持原值
                    }
                }
            }
        }

        return $data;
    }
}

// 使用示例
$event = [
    'title' => '技术会议',
    'date' => new DateTime('2023-10-15 14:00:00'),
    'participants' => [
        ['name' => '张三', 'join_time' => new DateTime('2023-10-15 13:45:00')],
        ['name' => '李四', 'join_time' => new DateTime('2023-10-15 13:50:00')]
    ]
];

try {
    $json = AdvancedJsonHelper::encodeWithDates($event);
    echo "包含日期的 JSON:\n" . $json . "\n";

    // 解码时指定日期字段
    $dateFields = ['date', 'join_time'];
    $decoded = AdvancedJsonHelper::decodeWithDates($json, $dateFields);

    echo "解码后的日期类型: " . get_class($decoded['date']) . "\n";
    echo "会议时间: " . $decoded['date']->format('Y年m月d日 H:i') . "\n";

} catch (Exception $e) {
    echo "错误: " . $e->getMessage() . "\n";
}
?>

3. 性能优化建议

  • 缓存 JSON 编码结果:对于不经常变化的数据,缓存编码结果避免重复处理
  • 使用合适的选项:根据需求选择合适的 JSON 选项,避免不必要的处理
  • 处理大数据集时分块:对于大型数据集,考虑分块处理避免内存问题
  • 验证输入数据:在处理外部 JSON 数据前先进行验证
  • 使用流式处理:对于非常大的 JSON 文件,考虑使用流式解析器