JSON (JavaScript Object Notation) 是輕量級資料交換格式,易讀寫、易機器解析、跨語言通用。基於兩大結構:
{ "key": "value" }[1, "two", { "nested": true }]{
"string": "值必須雙引號",
"number": 123.45,
"boolean": true,
"null": null,
"array": [1, 2, 3],
"object": { "nested": "value" }
}
注意:鍵名必須雙引號、無尾隨逗號、不支援註解。
const jsonStr = '{"name":"John","age":30}';
const obj = JSON.parse(jsonStr); // 字串 -> 物件
const str = JSON.stringify(obj); // 物件 -> 字串
const str2 = JSON.stringify(obj, null, 2); // 美化縮排
obj.name; // "John"
obj['age']; // 30
obj.skills = ['PHP', 'JS']; // 新增屬性
delete obj.age; // 刪除屬性
const clone = JSON.parse(JSON.stringify(obj)); // 簡單深層複製 (不支援函數、Date、RegExp、循環參考)
| 旗標 | 用途 |
|---|---|
JSON_UNESCAPED_UNICODE | 不將中文轉為 \uXXXX (PHP 5.4+) |
JSON_UNESCAPED_SLASHES | 不轉義 / (PHP 5.4+) |
JSON_NUMERIC_CHECK | 數字字串轉數字 (慎用) |
JSON_PRETTY_PRINT | 美化輸出 |
JSON_PRESERVE_ZERO_FRACTION | 浮點數保留 .0 (PHP 7.1+) |
JSON_THROW_ON_ERROR | 錯誤拋出例外 (PHP 7.3+) |
<?php
$data = [
'user' => '張三',
'email' => 'zhang@example.com',
'tags' => ['vip', 'beta'],
'score' => 98.5,
'active' => true,
];
// 標準輸出 (中文會被 Unicode 轉義)
echo json_encode($data);
// {"user":"\u5f20\u4e09","email":"zhang@example.com","tags":["vip","beta"],"score":98.5,"active":true}
// 友善輸出 (生產環境建議)
$options = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT;
echo json_encode($data, $options);
/*
{
"user": "張三",
"email": "zhang@example.com",
"tags": ["vip", "beta"],
"score": 98.5,
"active": true
}
*/
// 解碼
$json = '{"id":1,"name":"李四"}';
$obj = json_decode($json); // stdClass 物件
$arr = json_decode($json, true); // 關聯陣列 (建議)
echo $arr['name']; // 李四
// 錯誤處理 (PHP 7.3+)
try {
$data = json_decode($invalidJson, true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
error_log('JSON 解析失敗: ' . $e->getMessage());
}
?>
// jQuery
$.ajax({
url: '/api/user',
method: 'POST',
contentType: 'application/json',
data: JSON.stringify({ name: '王五', role: 'admin' }),
dataType: 'json',
success: (res) => console.log(res)
});
// Fetch (現代標準)
fetch('/api/user', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
body: JSON.stringify({ name: '王五', role: 'admin' })
}).then(r => r.json()).then(console.log);
<?php
// 僅接受 application/json
if (($_SERVER['CONTENT_TYPE'] ?? '') !== 'application/json') {
http_response_code(415);
exit('Unsupported Media Type');
}
$input = file_get_contents('php://input');
$data = json_decode($input, true, 512, JSON_THROW_ON_ERROR);
// 驗證 (建議使用 valitron/respect-validation 等庫)
if (empty($data['name'])) {
http_response_code(400);
echo json_encode(['error' => 'name required'], JSON_UNESCAPED_UNICODE);
exit;
}
// 處理邏輯...
echo json_encode(['id' => 123, 'message' => 'Created'], JSON_UNESCAPED_UNICODE);
<!-- 前端 -->
<script>
function callback(data) { console.log(data); }
</script>
<script src="https://api.example.com/data?callback=callback"></script>
<?php // 後端 -->
$callback = $_GET['callback'] ?? 'callback';
$data = ['time' => time()];
echo "$callback(" . json_encode($data) . ");";
<?php
// 允許特定來源
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
$allowed = ['https://app.example.com', 'https://admin.example.com'];
if (in_array($origin, $allowed, true)) {
header("Access-Control-Allow-Origin: $origin");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
}
// 預檢請求
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(204);
exit;
}
| 問題 | 原因 | 解決 |
|---|---|---|
| 中文變 \uXXXX | 預設編碼 | JSON_UNESCAPED_UNICODE |
| 大整數精度遺失 | JS Number 53 位精度 | 後端傳字串 "id": "123456789012345678" |
| 循環參考錯誤 | 物件互相引用 | 序列化前移除循環或用 DTO |
| BOM 導致解析失敗 | 檔案存儲含 BOM | 儲存為 UTF-8 without BOM |
| 控制字元導致錯誤 | 資料含 \x00-\x1F | 清洗資料或 JSON_INVALID_UTF8_IGNORE (PHP 7.2+) |
composer require justinrainbow/json-schema
<?php
use JsonSchema\Validator;
use JsonSchema\Constraints\Constraint;
$schema = json_decode('{
"type": "object",
"required": ["email"],
"properties": {
"email": { "type": "string", "format": "email" },
"age": { "type": "integer", "minimum": 18 }
}
}', true);
$validator = new Validator();
$validator->validate($inputData, $schema);
if (!$validator->isValid()) {
foreach ($validator->getErrors() as $err) {
echo $err['property'] . ': ' . $err['message'] . "\n";
}
}
?>
JSON 是現代 Web 開發的通用語言,掌握其規範、編解碼選項、傳輸協定與驗證機制,能大幅提升前後端協作效率與系統穩定度。