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

PHP 取得 MySQL 資料表欄位名稱的實用方法

     編輯:PHP 相關知識

在動態建構 SQL、自動產生表單、資料匯出等場景中,程式化取得資料表欄位名稱是常見需求。本文介紹從傳統 mysql_* 函數到現代 PDO 的多種做法,並說明資訊架構查詢的標準用法。

⚠️ 重要提醒:棄用 mysql_* 函數

原範例使用的 mysql_connect、mysql_list_fields 等函數 自 PHP 5.5.0 棄用,PHP 7.0.0 完全移除。新專案請務必改用 PDO 或 mysqli。

方法一:PDO + INFORMATION_SCHEMA(推薦、跨資料庫相容)

<?php
function getTableColumnsPDO(PDO $pdo, string $database, string $table): array {
    $sql = "
        SELECT COLUMN_NAME
        FROM INFORMATION_SCHEMA.COLUMNS
        WHERE TABLE_SCHEMA = :db
          AND TABLE_NAME = :tbl
        ORDER BY ORDINAL_POSITION
    ";
    $stmt = $pdo->prepare($sql);
    $stmt->execute([':db' => $database, ':tbl' => $table]);
    return $stmt->fetchAll(PDO::FETCH_COLUMN); // 直接回傳一維陣列
}

// 使用範例
$pdo = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8mb4', 'user', 'pass', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);

$columns = getTableColumnsPDO($pdo, 'testdb', 'users');
print_r($columns);
/*
Array
(
    [0] => id
    [1] => username
    [2] => email
    [3] => created_at
)
*/
?>

方法二:mysqli + INFORMATION_SCHEMA

<?php
function getTableColumnsMySQLi(mysqli $mysqli, string $database, string $table): array {
    $sql = "
        SELECT COLUMN_NAME
        FROM INFORMATION_SCHEMA.COLUMNS
        WHERE TABLE_SCHEMA = ?
          AND TABLE_NAME = ?
        ORDER BY ORDINAL_POSITION
    ";
    $stmt = $mysqli->prepare($sql);
    $stmt->bind_param('ss', $database, $table);
    $stmt->execute();
    $result = $stmt->get_result();
    $columns = [];
    while ($row = $result->fetch_row()) {
        $columns[] = $row[0];
    }
    return $columns;
}
?>

方法三:PDO::getColumnMeta(僅限查詢結果集,非資料表結構)

若已執行 SELECT * FROM table LIMIT 0,可從結果集取得欄位中繼資料:

<?php
$stmt = $pdo->query('SELECT * FROM users LIMIT 0');
$meta = [];
for ($i = 0; $i < $stmt->columnCount(); $i++) {
    $meta[] = $stmt->getColumnMeta($i)['name'];
}
print_r($meta);
?>

限制:需先執行查詢、驅動程式支援度不一(MySQL 支援、PostgreSQL 需額外設定)、無法取得完整結構定義(型別、長度、預設值等)。

方法四:DESCRIBE / SHOW COLUMNS(MySQL 專用,簡潔但非標準 SQL)

<?php
// PDO
$stmt = $pdo->query("DESCRIBE `users`");
$columns = $stmt->fetchAll(PDO::FETCH_COLUMN, 0); // Field 欄位

// 或
$stmt = $pdo->query("SHOW COLUMNS FROM `users`");
$columns = $stmt->fetchAll(PDO::FETCH_COLUMN, 0);
?>

進階:取得完整欄位定義(型別、長度、預設值、註解等)

<?php
function getTableSchema(PDO $pdo, string $database, string $table): array {
    $sql = "
        SELECT 
            COLUMN_NAME       AS `name`,
            COLUMN_TYPE       AS `type`,
            IS_NULLABLE       AS `nullable`,
            COLUMN_DEFAULT    AS `default`,
            COLUMN_KEY        AS `key`,
            EXTRA             AS `extra`,
            COLUMN_COMMENT    AS `comment`
        FROM INFORMATION_SCHEMA.COLUMNS
        WHERE TABLE_SCHEMA = :db
          AND TABLE_NAME = :tbl
        ORDER BY ORDINAL_POSITION
    ";
    $stmt = $pdo->prepare($sql);
    $stmt->execute([':db' => $database, ':tbl' => $table]);
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}

// 輸出範例
/*
Array
(
    [0] => Array
        (
            [name] => id
            [type] => bigint(20) unsigned
            [nullable] => NO
            [default] => 
            [key] => PRI
            [extra] => auto_increment
            [comment] => 主鍵 ID
        )
    [1] => Array
        (
            [name] => email
            [type] => varchar(255)
            [nullable] => NO
            [default] => 
            [key] => UNI
            [extra] => 
            [comment] => 使用者信箱
        )
)
*/
?>

實務應用範例:動態產生 INSERT SQL

<?php
function buildInsertSQL(string $table, array $data, array $columns): string {
    // 過濾資料中不存在於資料表的鍵
    $fields = array_intersect_key($data, array_flip($columns));
    if (empty($fields)) {
        throw new InvalidArgumentException('無有效欄位資料');
    }
    
    $cols = implode('`, `', array_keys($fields));
    $placeholders = ':' . implode(', :', array_keys($fields));
    
    return "INSERT INTO `$table` (`$cols`) VALUES ($placeholders)";
}

// 使用
$columns = getTableColumnsPDO($pdo, 'testdb', 'users');
$userData = [
    'username' => 'john',
    'email' => 'john@example.com',
    'invalid_field' => 'hack', // 會被自動過濾
];
$sql = buildInsertSQL('users', $userData, $columns);
$stmt = $pdo->prepare($sql);
$stmt->execute($userData); // PDO 自動綁定同名參數
?>

總結比較表

方法適用場景優點缺點
INFORMATION_SCHEMA (PDO/mysqli)通用、需完整結構、跨資料庫標準 SQL、資訊完整、支援參數綁定防注入查詢較複雜、需權限存取 information_schema
DESCRIBE / SHOW COLUMNSMySQL 專用、快速原型語法簡短、直觀非標準、難以參數化資料表名、資訊較少
PDO::getColumnMeta已有查詢結果集、僅需欄位名無額外查詢需先查詢、驅動相依、資訊有限

建議採用 PDO + INFORMATION_SCHEMA 作為標準做法,兼具安全性、可攜性與資訊完整度。

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