PHP JSON 处理:json_encode/json_decode 及常用技巧

小飞兽 PHP 22 次阅读 2026-07-16

JSON 基础

JSON(JavaScript Object Notation)是一种轻量级数据交换格式,PHP 与前端(JavaScript)之间的数据交互几乎都用 JSON。

一、json_encode — PHP 转 JSON

基本用法

<?php\n$data = [\n    'name' => '张三',\n    'age' => 25,\n    'city' => '绍兴',\n    'skills' => ['PHP', 'JavaScript', 'Python'],\n    'active' => true,\n];\n\n$json = json_encode($data);\necho $json;\n// {"name":"张三","age":25,"city":"绍兴","skills":["PHP","JavaScript","Python"],"active":true}\n?>

格式化输出(美化)

<?php\n$data = ['name' => '张三', 'age' => 25];\n\n// 不格式化(压缩在一行)\njson_encode($data);\n\n// 格式化(带缩进)— 调试友好\njson_encode($data, JSON_PRETTY_PRINT);\n// {\n//     "name": "张三",\n//     "age": 25\n// }\n\n// 中文 Unicode 转义问题\n// 默认中文会被转成 \\u4e2d\\u6587\necho json_encode(['name' => '张三']);\n// {"name":"\\u5f20\\u4e09"}\n\n// 解决方案:JSON_UNESCAPED_UNICODE\njson_encode($data, JSON_UNESCAPED_UNICODE);\n// {"name":"张三","age":25}\n?>

常用 json_encode 选项

<?php\n$data = [\n    'name' => '',\n    'price' => 99.9,\n    'desc' => '产品"A"介绍',\n];\n\n// 多个选项用 | 组合\njson_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);\n\n// 选项说明:\n// JSON_UNESCAPED_UNICODE  不转义中文\n// JSON_UNESCAPED_SLASHES  不转义斜杠 /\n// JSON_PRETTY_PRINT       格式化输出\n// JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT  常用组合\n?>

处理中文和特殊字符

<?php\n// 问题:中文被 Unicode 转义\necho json_encode(['name' => '张三']);\n// {"name":"\\u5f20\\u4e09"}\n\n// 解决\njson_encode(['name' => '张三'], JSON_UNESCAPED_UNICODE);\n// {"name":"张三"}\n\n// 问题:& < > 被转义\necho json_encode(['url' => 'https://example.com/?a=1&b=2']);\n// {"url":"https:\\/\\/example.com\\/?a=1&b=2"}\n\n// 解决\njson_encode(['url' => 'https://example.com/?a=1&b=2'], JSON_UNESCAPED_SLASHES);\n// {"url":"https://example.com/?a=1&b=2"}\n?>

二、json_decode — JSON 转 PHP

基本用法

<?php\n$json = \'{"name":"张三","age":25,"city":"绍兴","skills":["PHP","JavaScript"],"active":true}\';\n\n// 解码为关联数组\n$data = json_decode($json, true);\nprint_r($data);\n// Array ( [name] => 张三 [age] => 25 [city] => 绍兴 [skills] => Array... )\n\necho $data['name'];  // 张三\necho $data['skills'][0];  // PHP\n?>

解码为对象

<?php\n$json = \'{"name":"张三","age":25}\';\n\n// 解码为 stdClass 对象(第二个参数 false 或省略)\n$obj = json_decode($json);\necho $obj->name;  // 张三\necho $obj->age;   // 25\n\n// 解码为数组(第二个参数 true)\n$arr = json_decode($json, true);\necho $arr['name'];  // 张三\n?>

解码多维 JSON

<?php\n$json = \'[\n    {"name": "张三", "score": 92},\n    {"name": "李四", "score": 85},\n    {"name": "王五", "score": 78}\n]\';\n\n$list = json_decode($json, true);\nforeach ($list as $item) {\n    echo "{$item[\'name\']}: {$item[\'score\']}分\\n";\n}\n?>

三、JSON 与 PHP 类型对应

<?php\n// JSON 数组 → PHP 数组\njson_decode('[1,2,3]', true);  // [1, 2, 3]\n\n// JSON 对象 → PHP 数组(assoc=true)或 stdClass(assoc=false)\njson_decode(\'{"a":1}\', true);  // ['a'=>1]\njson_decode(\'{"a":1}\', false); // (object)['a'=>1]\n\n// JSON null → PHP null\njson_decode('null');  // null\n\n// 注意数值精度\njson_decode('9007199254740993');  // 9007199254740992(超过 JS Number 安全范围)\n?>

四、JSON 错误处理

<?php\n$json = '{invalid json}';\n\n// json_last_error() 获取错误码\njson_decode($json);\n$error_code = json_last_error();\necho json_last_error_msg();  // 控制版面不合法\n\n// 完整错误处理函数\nfunction safe_json_decode(string $json, bool $assoc = true) {\n    $data = json_decode($json, $assoc);\n    if (json_last_error() !== JSON_ERROR_NONE) {\n        throw new Exception('JSON 解析失败:' . json_last_error_msg());\n    }\n    return $data;\n}\n\ntry {\n    $data = safe_json_decode($json);\n} catch (Exception $e) {\n    echo $e->getMessage();  // JSON 解析失败:控制版面不合法\n}\n?>

五、实战应用

API 响应格式

<?php\n// 统一的 API 响应格式\nfunction api_response(mixed $data = null, string $message = '', int $code = 0): void {\n    header('Content-Type: application/json; charset=utf-8');\n    echo json_encode([\n        'code' => $code,\n        'message' => $message,\n        'data' => $data,\n        'timestamp' => time(),\n    ], JSON_UNESCAPED_UNICODE);\n    exit;\n}\n\n// 使用\nif ($user = find_user_by_id($id)) {\n    api_response($user, '获取成功', 0);\n} else {\n    api_response(null, '用户不存在', 404);\n}\n?>

缓存数据

<?php\n$cache_file = '/tmp/users.json';\n\n// 读缓存\nif (file_exists($cache_file) && filemtime($cache_file) > time() - 3600) {\n    $users = json_decode(file_get_contents($cache_file), true);\n} else {\n    // 查数据库\n    $users = $db->query('SELECT * FROM users')->fetchAll();\n    // 写缓存\n    file_put_contents($cache_file, json_encode($users, JSON_UNESCAPED_UNICODE));\n}\n?>

配置存储

<?php\n// config.json\n// {\n//     "host": "localhost",\n//     "port": 3306,\n//     "dbname": "myapp",\n//     "debug": true\n// }\n\n$config = json_decode(file_get_contents(__DIR__ . '/config.json'), true);\necho $config['host'];  // localhost\n?>

六、JSON_INVALID_UTF8_IGNORE(PHP 7.2+)

<?php\n// 忽略无效 UTF-8 字符\n$data = ["name" => "test\x80\x90"];\necho json_encode($data, JSON_INVALID_UTF8_IGNORE);\n// {"name":"test"}\n\n// 或者替换为 Unicode 转义\n$data = ["name" => "test\x80\x90"];\necho json_encode($data, JSON_INVALID_UTF8_SUBSTITUTE);\n// {"name":"test\\ufffd\\ufffd"}\n?>

总结

    • json_encode() 把 PHP 转为 JSON,json_decode() 把 JSON 转为 PHP
    • JSON_UNESCAPED_UNICODE 保留中文,JSON_UNESCAPED_SLASHES 保留斜杠
    • json_decode($json, true) 转数组,false 转对象
  • 每次 JSON 操作后用 json_last_error_msg() 检查错误
  • API 响应统一用 header('Content-Type: application/json')