PHP JSON 处理:json_encode/json_decode 及常用技巧
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 转为 PHPJSON_UNESCAPED_UNICODE保留中文,JSON_UNESCAPED_SLASHES保留斜杠json_decode($json, true)转数组,false转对象- 每次 JSON 操作后用
json_last_error_msg()检查错误 - API 响应统一用
header('Content-Type: application/json')