在 AJAX 技術普及的早期,XML 是數據交換的標準格式。然而,XML 的樹狀結構雖然靈活,但在 JavaScript 端解析卻相對繁瑣,需要操作 DOM 樹、節點遍歷,代碼冗長且易出錯。JSON (JavaScript Object Notation) 的出現徹底改變了這一局面:它本質上是 JavaScript 物件字面量語法的子集,原生支持於 JS 中,解析速度極快,數據體積更小,結構清晰易讀,迅速成為 Web API 的事實標準。
自 PHP 5.2 起,核心擴展內置了 JSON 功能,提供兩個核心函數,用法與 serialize/unserialize 極為相似:
json_encode($value):將 PHP 變數(陣列、物件)編碼為 JSON 字符串。json_decode($json, $assoc = false):將 JSON 字符串解碼為 PHP 變數。第二個參數為 true 時返回關聯陣列,否則返回 stdClass 物件。核心限制: json_encode 強制要求輸入為 UTF-8 編碼。若 PHP 源文件或數據庫編碼為 GB2312/GBK,直接編碼包含中文的數據會導致中文變為 null 或輸出 Unicode 轉義序列 (如 \u4e2d\u6587)。
<?php
// 示例數據
$arr = array(
'name' => '陳毅鑫',
'nick' => '深空',
'contact' => array(
'email' => 'shenkong@qq.com',
'website' => 'https://www.example.com'
)
);
// 情況一:源文件為 UTF-8 (推薦現代開發標準)
$json_string = json_encode($arr);
echo $json_string;
// 輸出: {"name":"\u9648\u6bc5\u946b","nick":"\u6df1\u7a7a","contact":{"email":"shenkong@qq.com","website":"http:\/\/www.example.com"}}
// 註:預設會轉義 Unicode,PHP 5.4+ 可用 JSON_UNESCAPED_UNICODE 保持中文可讀
// 情況二:源文件為 GB2312 - 必須轉碼
// $arr_utf8 = array_map('iconv', $arr, ['gb2312', 'utf-8']); // 簡寫需遞歸處理多維陣列
// $json_string = json_encode($arr_utf8);
?>
<?php
$json_string = '{"name":"\u9648\u6bc5\u946b","nick":"\u6df1\u7a7a","contact":{"email":"shenkong@qq.com","website":"http:\/\/www.example.com"}}';
// 1. 解碼為物件 (預設)
$obj = json_decode($json_string);
echo $obj->name; // 輸出: 陳毅鑫 (自動解碼 Unicode)
echo $obj->contact->email;
// 2. 解碼為關聯陣列 (推薦,操作更直觀)
$arr = json_decode($json_string, true); // 關鍵參數 true
echo $arr['name'];
echo $arr['contact']['website'];
// 3. 錯誤處理 (PHP 5.3+)
if (json_last_error() !== JSON_ERROR_NONE) {
echo 'JSON 解析錯誤: ' . json_last_error_msg();
}
?>
受瀏覽器同源策略限制,Ajax 無法直接請求不同域名下的接口。JSONP (JSON with Padding) 是一種經典的跨域解決方案,利用 <script> 標籤不受同源策略限制的特性。
getProfile(data)。<script src="https://api.other.com/profile.php?callback=getProfile"></script>。callback 參數,輸出 getProfile({...json數據...})。前端頁面 (index.html)
<!DOCTYPE html>
<html>
<body>
<div id="nick">加載中...</div>
<script>
function getProfile(str) {
// str 已經是 JS 物件 (若後端輸出正確)
document.getElementById('nick').innerHTML = '暱稱:' + str.nick;
}
// 動態插入 script 標籤發起請求
var script = document.createElement('script');
script.src = 'https://www.phpfans.org/demo/profile.php?callback=getProfile';
document.head.appendChild(script);
</script>
</body>
</html>
後端接口 (profile.php)
<?php
$arr = array(
'name' => '陳毅鑫',
'nick' => '深空',
'contact' => array(
'email' => 'shenkong@qq.com',
'website' => 'https://www.bkjia.com'
)
);
$json_string = json_encode($arr);
// 關鍵:獲取回調函數名,包裹 JSON 字符串
$callback = isset($_GET['callback']) ? $_GET['callback'] : 'callback';
// 安全過濾:防止 XSS,僅允許字母數字下劃線
if (!preg_match('/^[a-zA-Z0-9_]+$/', $callback)) {
exit('Invalid callback');
}
// 輸出 JavaScript 語句
header('Content-Type: application/javascript; charset=utf-8');
echo $callback . '(' . $json_string . ');';
?>
雖然 JSONP 簡單易用,但僅支持 GET 請求,且存在安全隱患 (CSRF、腳本注入)。現代開發強烈推薦使用 CORS:
header('Access-Control-Allow-Origin: *'); (或指定域名)JSON 以其輕量、原生兼容 JS、易於解析的優勢,成為現代 Web 數據交換的核心。PHP 內置函數讓編解碼極為簡單,但編碼統一 (UTF-8) 是避坑關鍵。跨域需求下,理解 JSONP 原理有助於掌握 Web 通信本質,但生產環境請優先採用 CORS 標準。