{
"aa": [
{"Id": "0", "title": "標題"},
{"Id": "1", "title": "標題"}
],
"bb": [
{"Id": "2", "title": "標題"},
{"Id": "3", "title": "標題"}
]
}
<?php
$data = [
'aa' => [
['Id' => 0, 'title' => '標題'],
['Id' => 1, 'title' => '標題'],
],
'bb' => [
['Id' => 2, 'title' => '標題'],
['Id' => 3, 'title' => '標題'],
],
];
// 核心參數說明
$options = JSON_PRETTY_PRINT // 縮排美化
| JSON_UNESCAPED_UNICODE // 中文不轉義
| JSON_UNESCAPED_SLASHES // 不轉義斜線
| JSON_NUMERIC_CHECK; // 數字字符串轉數字
header('Content-Type: application/json; charset=utf-8');
echo json_encode($data, $options);
{
"aa": [
{
"Id": 0,
"title": "標題"
},
{
"Id": 1,
"title": "標題"
}
],
"bb": [
{
"Id": 2,
"title": "標題"
},
{
"Id": 3,
"title": "標題"
}
]
}
PHP 5.3 及以下無 JSON_PRETTY_PRINT,需手動格式化:
<?php
function jsonFormat(mixed $data, string $indent = ' '): string
{
// 1. 遞歸 URL 編碼保護中文
array_walk_recursive($data, function (&$val) {
if (is_string($val)) $val = urlencode($val);
});
// 2. 編碼
$json = json_encode($data);
// 3. 解碼還原中文
$json = urldecode($json);
// 4. 手動縮排
$result = '';
$pos = 0;
$len = strlen($json);
$newline = "\n";
$inString = false;
$escape = false;
for ($i = 0; $i < $len; $i++) {
$char = $json[$i];
// 處理字符串邊界
if ($char === '"' && !$escape) {
$inString = !$inString;
}
$escape = ($char === '\\' && !$escape);
// 結構字符處理
if (!$inString) {
if ($char === '}' || $char === ']') {
$result .= $newline;
$pos--;
$result .= str_repeat($indent, $pos);
}
}
$result .= $char;
if (!$inString) {
if ($char === ',' || $char === '{' || $char === '[') {
$result .= $newline;
if ($char === '{' || $char === '[') {
$pos++;
}
$result .= str_repeat($indent, $pos);
}
}
}
return $result;
}
// 使用
echo jsonFormat($data);
$data = ['price' => '199.00', 'count' => '10'];
echo json_encode($data, JSON_NUMERIC_CHECK);
// {"price":199.0,"count":10}
$data = ['order_id' => '1234567890123456789'];
// 不加 JSON_NUMERIC_CHECK,或手動轉型
echo json_encode($data); // {"order_id":"1234567890123456789"}
class User implements JsonSerializable
{
private string $name;
private string $email; // 敏感字段
public function __construct(string $name, string $email)
{
$this->name = $name;
$this->email = $email;
}
public function jsonSerialize(): array
{
return [
'name' => $this->name,
'email_masked' => $this->maskEmail($this->email),
];
}
private function maskEmail(string $email): string
{
[$local, $domain] = explode('@', $email);
return substr($local, 0, 1) . '***' . '@' . $domain;
}
}
echo json_encode(new User('張三', 'zhangsan@example.com'), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
function streamJsonArray(iterable $items): Generator
{
yield '[';
$first = true;
foreach ($items as $item) {
if (!$first) yield ',';
yield json_encode($item, JSON_UNESCAPED_UNICODE);
$first = false;
}
yield ']';
}
// 直接輸出到瀏覽器/文件
header('Content-Type: application/json');
foreach (streamJsonArray($hugeDataset) as $chunk) {
echo $chunk;
@ob_flush(); @flush();
}
| 問題 | 解決方案 |
|---|---|
| 中文變 \uXXXX | 加 JSON_UNESCAPED_UNICODE |
| 斜線變 \/ | 加 JSON_UNESCAPED_SLASHES |
| 浮點數精度丟失 | 用字符串存儲或 number_format |
| 循環引用報錯 | 實現 JsonSerializable 控制輸出 |
| 大數據記憶體溢出 | 流式生成器分塊輸出 |
現代 PHP 專案直接使用 json_encode 組合旗標即可滿足 99% 場景;僅在極舊環境或特殊串流需求時才需自定義格式化邏輯。