JSON (JavaScript Object Notation) 是輕量級資料交換格式,易於人閱讀、機器解析。PHP 5.2+ 內建支援,核心函數:
json_encode():PHP 變數 → JSON 字串json_decode():JSON 字串 → PHP 變數 (物件/陣列)json_encode 回傳 null 或空字串。解決:iconv('GBK', 'UTF-8', $str) 或 mb_convert_encoding()。JsonSerializable 介面控制輸出。// 編碼 string json_encode(mixed $value, int $flags = 0, int $depth = 512) // 解碼 mixed json_decode(string $json, bool $assoc = false, int $depth = 512, int $flags = 0)
常用 Flags:
| 常數 | 說明 |
|---|---|
JSON_UNESCAPED_UNICODE | 不轉義 Unicode (中文直接顯示,PHP 5.4+) |
JSON_UNESCAPED_SLASHES | 不轉義 / (PHP 5.4+) |
JSON_PRETTY_PRINT | 美化縮進輸出 (PHP 5.4+) |
JSON_NUMERIC_CHECK | 數字字串轉數值型別 (PHP 5.3.3+) |
JSON_FORCE_OBJECT | 索引陣列強制輸出為物件 |
$arr = [
'name' => '魏艷輝',
'nick' => '為夢翱翔',
'contact' => [
'email' => 'test@example.com',
'website' => 'https://example.com'
]
];
$json = json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
echo $json;
/*
{
"name": "魏艷輝",
"nick": "為夢翱翔",
"contact": {
"email": "test@example.com",
"website": "https://example.com"
}
}
*/
$json = '{"id":1,"name":"test","tags":["a","b"]}';
// 預設解碼為 stdClass 物件
$obj = json_decode($json);
echo $obj->name; // test
echo $obj->tags[0]; // a
// 第二參數 true 解碼為關聯陣列
$arr = json_decode($json, true);
echo $arr['name']; // test
echo $arr['tags'][1]; // b
<script>
// PHP 輸出的 JSON 直接賦值給 JS 變數
var data = {$json}; // 假設 PHP 已 echo json_encode($arr, JSON_UNESCAPED_UNICODE);
console.log(data.name); // 魏艷輝
console.log(data.contact.email); // test@example.com
</script>
關鍵:PHP 輸出時不加引號,前端直接當物件字面量使用。
// profile.php (被調用端)
$arr = ['name' => '張三', 'age' => 25];
$json = json_encode($arr, JSON_UNESCAPED_UNICODE);
$callback = $_GET['callback'] ?? 'callback';
echo "{$callback}({$json});"; // 輸出: callback({"name":"張三","age":25});
// index.html (調用端)
<script>
function callback(data) {
document.getElementById('name').innerText = data.name;
}
</script>
<div id="name"></div>
<script src="https://api.example.com/profile.php?callback=callback"></script>
// 現代瀏覽器 (IE8+)
var obj = JSON.parse(jsonString);
// 相容舊瀏覽器 (不推薦 eval)
var obj = eval('(' + jsonString + ')'); // 安全風險:可能執行惡意代碼
| PHP 結構 | json_encode 輸出 | JS 對應型別 |
|---|---|---|
物件 new StdClass | {"id":1,"name":"test"} | Object |
索引陣列 [1, 'a', 'b'] | [1,"a","b"] | Array |
關聯陣列 ['id'=>1] | {"id":1} | Object |
多維索引陣列 [[1,2],[3,4]] | [[1,2],[3,4]] | Array of Array |
多維關聯陣列 [['id'=>1],['id'=>2]] | [{"id":1},{"id":2}] | Array of Object |
規律:連續數字鍵 0..n-1 → JS Array,否則 → JS Object。
var jsonObj = {
// 屬性名/值成對
"property": "value",
"number": 123,
"bool": true,
"null": null,
"array": [1, 2, 3],
"nested": { "key": "val" },
// 函數屬性 (非標準 JSON,JS 物件才有)
"method": function() { return this.property; }
};
標準 JSON 不支援函數、註解、尾隨逗號,嚴格遵循 RFC 8259。
| 問題 | 原因 | 解決 |
|---|---|---|
| 中文變 \uXXXX | 預設轉義 Unicode | 加 JSON_UNESCAPED_UNICODE (PHP 5.4+) |
| json_encode 回傳 false/null | 非 UTF-8、資源型別、循環引用 | json_last_error_msg() 診斷;轉編碼、移除資源、實作 JsonSerializable |
| 大數字精度丟失 | JS Number 53 位精度限制 | 傳字串 "id": "12345678901234567890",JS 用 BigInt 或字串處理 |
| 解碼深度超限 | 巢狀超過 512 層 | 調整 depth 參數或重構資料結構 |
class User implements JsonSerializable {
private $id;
private $name;
private $password; // 敏感欄位不輸出
public function __construct($id, $name, $pwd) {
$this->id = $id;
$this->name = $name;
$this->password = $pwd;
}
public function jsonSerialize() {
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"}
json_encode() / json_decode()JSON_UNESCAPED_UNICODE 輸出可讀中文true 得關聯陣列JSON.parse()JsonSerializable 精確控制輸出掌握這些核心技巧,即可在 PHP 專案中高效、安全地處理 JSON 資料交換。