首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP json_encode 完整應用指南:從資料庫到前端圖表的資料流

     編輯:PHP 綜合知識

json_encode() 是 PHP 將陣列/物件序列化為 JSON 字串的核心函式。本文從資料庫查詢、陣列組裝、編碼選項、前端 AJAX 接收、常見坑點 (中文 Unicode、大數字精度、循環引用) 完整說明,並示範輸出供 ECharts/Chart.js 直接使用的資料結構。

基本流程

  1. 資料庫查詢 → 關聯陣列
  2. 重組為前端所需結構 (如 [xData, yData, labels])
  3. json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
  4. 設定 Content-Type: application/json; charset=utf-8 輸出

完整後端範例 (PDO + MySQL)

<?php
// columndata.php
header('Content-Type: application/json; charset=utf-8');

try {
    $pdo = new PDO(
        'mysql:host=localhost;dbname=stats;charset=utf8mb4',
        'user', 'pass',
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
    );

    $begin = $_GET['BeginTime'] ?? date('Y-m-01');
    $end   = $_GET['EndTime']   ?? date('Y-m-d');
    $kw    = $_GET['keyword']   ?? '';

    $sql = 'SELECT `EventDate`, `data` FROM `metrics`
            WHERE `EventDate` BETWEEN ? AND ?'
         . ($kw ? ' AND `tag` LIKE ?' : '')
         . ' ORDER BY `EventDate`';

    $params = [$begin, $end];
    if ($kw) $params[] = "%{$kw}%";

    $stmt = $pdo->prepare($sql);
    $stmt->execute($params);

    $xData = [];
    $yData = [];
    foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
        $xData[] = $row['EventDate'];           // 日期字串
        $yData[] = (int) $row['data'];          // 強制整數
    }

    // 組裝前端 ECharts/Chart.js 直接可用的結構
    $payload = [
        'xAxis' => $xData,
        'series' => [[
            'name'  => '數值',
            'type'  => 'line',
            'data'  => $yData,
        ]],
        'meta' => [
            'count'     => count($xData),
            'generated' => date('c'),
        ],
    ];

    // 關鍵選項說明:
    // JSON_UNESCAPED_UNICODE : 中文不轉 \uXXXX,減小體積且可讀
    // JSON_UNESCAPED_SLASHES : 不轉義 /,URL 更乾淨
    // JSON_NUMERIC_CHECK     : 數字字串轉真數字 (謹慎用,大整數可能溢位)
    // JSON_PRESERVE_ZERO_FRACTION : 保留 1.0 不變 1
    echo json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

} catch (Throwable $e) {
    http_response_code(500);
    echo json_encode(['error' => $e->getMessage()], JSON_UNESCAPED_UNICODE);
}

前端 AJAX 接收 (jQuery / Fetch / Axios)

// 現代 Fetch API (推薦)
async function loadChartData() {
    const params = new URLSearchParams({
        BeginTime: '2024-01-01',
        EndTime:   '2024-12-31',
        keyword:   'sales'
    });
    const resp = await fetch(`columndata.php?${params}`);
    if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
    const data = await resp.json(); // 自動解析 JSON

    // data 結構:{ xAxis: [...], series: [{data: [...]}], meta: {...} }
    initChart(data.xAxis, data.series[0].data);
}

// 傳統 jQuery (相容舊專案)
$.ajax({
    url: 'columndata.php',
    dataType: 'json',           // 自動 parseJSON
    cache: false,
    data: { BeginTime: '2024-01-01', EndTime: '2024-12-31' },
    success: function (data) {
        if (data.error) return alert(data.error);
        initChart(data.xAxis, data.series[0].data);
    },
    error: function () { alert('請求失敗'); }
});

常見坑點與解決方案

現象原因解決
中文變 \uXXXX預設逃逸 Unicode加 JSON_UNESCAPED_UNICODE
URL 變 http:\/\/example.com預設逃逸斜線加 JSON_UNESCAPED_SLASHES
大整數 (ID) 變科學記號或失真JS Number 53-bit 限制後端輸出字串 "id": "1234567890123456789",前端用 BigInt 或字串處理
浮點數 0.1+0.2=0.30000000000004IEEE 754 二進制浮點資料庫存 DECIMAL(10,2),PHP 用 number_format($v, 2, '.', '') 或 bcmath
循環引用錯誤 (Recursion detected)物件互相參考實作 JsonSerializable 或用 DTO 陣列
前端收到字串而非物件未送 Content-Type: application/json確實送標頭,或前端 JSON.parse()

進階:實作 JsonSerializable 精準控制輸出

class ChartDataset implements JsonSerializable
{
    private array $xAxis;
    private array $yData;
    private string $label;

    public function __construct(array $x, array $y, string $label)
    {
        $this->xAxis = $x;
        $this->yData = $y;
        $this->label = $label;
    }

    public function jsonSerialize(): array
    {
        return [
            'labels'   => $this->xAxis,
            'datasets' => [[
                'label'           => $this->label,
                'data'            => $this->yData,
                'borderColor'     => 'rgb(54, 162, 235)',
                'backgroundColor' => 'rgba(54, 162, 235, 0.2)',
                'fill'            => false,
                'tension'         => 0.1,
            ]],
        ];
    }
}

// 使用
$dataset = new ChartDataset($dates, $values, '銷售額');
echo json_encode($dataset, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

效能優化建議

  • 啟用 OPcache:PHP 內建,編譯後直接執行 bytecode。
  • 資料庫索引:EventDate、tag 加索引,避免全表掃描。
  • 分頁/限制筆數:圖表通常只需近 30~365 筆,加 LIMIT 365。
  • HTTP 快取:送出 ETag / Cache-Control: max-age=60,減少重複請求。
  • gzip 壓縮:Nginx/Apache 開啟 gzip_types application/json,JSON 壓縮率極高 (常 >80%)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved