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

PHP 查詢 MySQL 並輸出 JSON 的最佳實踐指南

     編輯:PHP 綜合知識

核心需求與常見陷阱

API 介面開發中,資料庫查詢結果轉 JSON 是高頻操作。原文提供的兩個範例雖能跑通,但存在嚴重問題:使用已棄用的 mysql_* 函式、缺乏錯誤處理、SQL 直接拼接變數導致注入風險、分頁參數未驗證、資源釋放不完整。

現代化重構範例

資料庫連線層(PDO 單例模式)

class Database {
    private static ?\PDO $instance = null;
    private function __construct() {}
    public static function getInstance(): \PDO {
        if (self::$instance === null) {
            $dsn = "mysql:host=localhost;dbname=jilinwula;charset=utf8mb4";
            self::$instance = new \PDO($dsn, 'root', 'root', [
                \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
                \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
                \PDO::ATTR_EMULATE_PREPARES => false,
            ]);
        }
        return self::$instance;
    }
}

分頁查詢服務類

class UserService {
    public function getUsersPaginated(int $page = 1, int $pageSize = 15): array {
        $page = max(1, $page);
        $pageSize = min(max(1, $pageSize), 100); // 限制最大頁長
        $offset = ($page - 1) * $pageSize;

        $pdo = Database::getInstance();
        $stmt = $pdo->prepare("SELECT `username`, `email`, `created_at` FROM `userinfo` LIMIT ? OFFSET ?");
        $stmt->bindValue(1, $pageSize, \PDO::PARAM_INT);
        $stmt->bindValue(2, $offset, \PDO::PARAM_INT);
        $stmt->execute();
        $data = $stmt->fetchAll();

        // 總筆數查詢(可優化為快取)
        $total = (int)$pdo->query("SELECT COUNT(*) FROM `userinfo`")->fetchColumn();

        return [
            'data' => $data,
            'meta' => [
                'current_page' => $page,
                'page_size' => $pageSize,
                'total' => $total,
                'last_page' => (int)ceil($total / $pageSize),
            ],
        ];
    }
}

控制器層輸出標準化

header('Content-Type: application/json; charset=utf-8');
header('X-Content-Type-Options: nosniff');

try {
    $page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
    $pageSize = isset($_GET['pageSize']) ? (int)$_GET['pageSize'] : 15;
    $service = new UserService();
    $result = $service->getUsersPaginated($page, $pageSize);
    echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
} catch (\Throwable $e) {
    http_response_code(500);
    echo json_encode([
        'error' => 'Internal Server Error',
        'message' => $e->getMessage(), // 生產環境應隱藏詳細錯誤
    ], JSON_UNESCAPED_UNICODE);
}

關鍵最佳實踐總結

維度不良實踐推薦做法
資料庫驅動mysql_* 函式PDO / mysqli + 預處理語句
字元編碼SET NAMES UTF8DSN 中指定 charset=utf8mb4
錯誤處理die()/or die()try-catch + 統一異常處理器
輸出格式直接 echo json_encode設定正確 Content-Type + JSON 選項常數
分頁參數直接使用 $_GET型別轉換 + 範圍驗證 + 預設值
資源管理手動 free/closePDO 物件自動管理 / 依賴注入容器

進階優化方向

  • 引入快取層:熱門查詢結果存入 Redis,降低資料庫壓力
  • 游標分頁:大資料量場景下用 WHERE id > ? ORDER BY id LIMIT ? 替代 OFFSET
  • API 版本控制:URL 或 Header 區分版本,確保向後相容
  • 回應壓縮:啟用 gzip/brotli,減少傳輸頻寬
  • OpenAPI/Swagger 文件化:自動生成介面文件,提升前後端協作效率

結語

從「能跑通」到「生產可用」,中間隔著資料庫抽象層、參數驗證、異常處理、資源管理、安全防護等多層工程化建設。掌握 PDO 預處理、依賴注入、分層架構等核心技能,才能寫出經得起時間考驗的 PHP 程式碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved