JSON (JavaScript Object Notation) 是輕量級資料交換格式,PHP 5.2+ 內建 json_encode() / json_decode()。
<?php
header('Content-Type: application/json; charset=utf-8'); // 標準 MIME
// 或舊版相容
header('Content-Type: text/json; charset=utf-8');
<?php
$data = [
'status' => 'success',
'users' => [
['id' => 1, 'name' => '張三', 'email' => 'zhang@example.com'],
['id' => 2, 'name' => '李四', 'email' => 'li@example.com']
],
'meta' => ['total' => 2, 'page' => 1]
];
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
常用選項:
JSON_UNESCAPED_UNICODE:中文不轉 \uXXXX,可讀性佳JSON_PRETTY_PRINT:縮排格式化(開發除錯用)JSON_UNESCAPED_SLASHES:不轉義 /JSON_NUMERIC_CHECK:數值字串轉數字(謹慎使用)<?php
// 假設從資料庫查詢得到
$rows = [
['code' => '001', 'name' => '台灣', 'population' => 23000000],
['code' => '002', 'name' => '日本', 'population' => 125000000]
];
$obj = new stdClass();
$obj->total = count($rows);
$obj->rows = $rows;
echo json_encode($obj, JSON_UNESCAPED_UNICODE);
// {"total":2,"rows":[{"code":"001","name":"台灣",...},...]}
// 前端存取:data.rows[0].name
<?php
$arr = [
'total' => count($rows),
'rows' => $rows
];
echo json_encode($arr, JSON_UNESCAPED_UNICODE);
// 前端存取:data.rows[0].name (同樣運作)
現代 API 慣用純陣列結構,序列化/反序列化更直觀。
<?php
// api/users.php
header('Content-Type: application/json; charset=utf-8');
try {
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8mb4', 'user', 'pass');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$page = max(1, (int)($_GET['page'] ?? 1));
$limit = 10;
$offset = ($page - 1) * $limit;
$stmt = $pdo->prepare('SELECT id, username, email, created_at FROM users LIMIT ? OFFSET ?');
$stmt->bindValue(1, $limit, PDO::PARAM_INT);
$stmt->bindValue(2, $offset, PDO::PARAM_INT);
$stmt->execute();
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
$totalStmt = $pdo->query('SELECT COUNT(*) FROM users');
$total = $totalStmt->fetchColumn();
echo json_encode([
'success' => true,
'data' => $users,
'pagination' => [
'page' => $page,
'limit' => $limit,
'total' => (int)$total,
'pages' => (int)ceil($total / $limit)
]
], JSON_UNESCAPED_UNICODE);
} catch (PDOException $e) {
http_response_code(500);
echo json_encode([
'success' => false,
'error' => 'Database error',
'message' => $e->getMessage()
], JSON_UNESCAPED_UNICODE);
}
<script>
$.getJSON('api/users.php', {page: 1}, function(response) {
if (response.success) {
let html = '';
$.each(response.data, function(i, user) {
html += `<div class="user"><h4>${user.username}</h4><p>${user.email}</p></div>`;
});
$('#user-list').html(html);
// 處理分頁...
} else {
alert('錯誤:' + response.error);
}
}).fail(function() {
alert('網路請求失敗');
});
</script>
<script>
$.ajax({
url: 'api/users.php',
method: 'GET',
dataType: 'json',
data: {page: 1},
beforeSend: function() { $('#loading').show(); },
success: function(response) { /* ... */ },
error: function(xhr, status, error) {
console.error('AJAX Error:', status, error);
},
complete: function() { $('#loading').hide(); }
});
</script>
<?php
$json = '{"name":"張三","age":25,"skills":["PHP","JS","MySQL"]}';
// 解碼為關聯陣列(推薦,true 參數)
$arr = json_decode($json, true);
// ['name' => '張三', 'age' => 25, 'skills' => ['PHP','JS','MySQL']]
// 解碼為物件(預設)
$obj = json_decode($json);
// $obj->name, $obj->skills[0]
// 錯誤處理
$data = json_decode($input, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new Exception('JSON 解析失敗:' . json_last_error_msg());
}
| 問題 | 原因 | 解決 |
|---|---|---|
| 中文變 \uXXXX | 預設編碼行為 | 加 JSON_UNESCAPED_UNICODE |
| 數字變字串 | 資料庫驅動回傳字串 | JSON_NUMERIC_CHECK 或 PDO ATTR_STRINGIFY_FETCHES => false |
| 前端收到亂碼 | 編碼不一致 | 確認 PHP 檔案 UTF-8、資料庫 utf8mb4、header charset=utf-8 |
| 大數值精度遺失 | JS Number 限制 | ID 等大數值以字串輸出 |
| json_decode 回傳 null | JSON 格式錯誤/深度超限 | 檢查 json_last_error()、調整 json_decode($json, true, 512) 深度 |
application/json + charset=utf-8JSON_UNESCAPED_UNICODE{success, data, error, pagination}掌握 JSON 編解碼與前後端串接,是現代 PHP 開發核心技能。