游客发表
用PHP读一张表的编写部字所有字段,最直接的代段方式是查 INFORMATION_SCHEMA.COLUMNS。别急着用 SELECT * 然后 fetch_fields(),码读那个方法虽然能拿到字段名,取表e全但拿不到字段类型、编写部字是代段否为空、默认值、码读注释这些关键信息。取表e全真正要“全部字段”的编写部字完整定义,走 information_schema 才是代段正路。
假设数据库是码读 MySQL,表名 testtable,取表e全库名 testdb。编写部字先连上:
$pdo = new PDO('mysql:host=127.0.0.1;dbname=testdb;charset=utf8mb4',代段 'root', 'password'); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 然后执行查询。注意 TABLE_SCHEMA 要指定库名,码读不然会捞出整个实例里所有同名表的字段:
$sql = "SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULT, COLUMN_COMMENT, COLUMN_KEY, EXTRA FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = :db AND TABLE_NAME = :table ORDER BY ORDINAL_POSITION"; $stmt = $pdo->prepare($sql); $stmt->execute([':db' => 'testdb', ':table' => 'testtable']); $columns = $stmt->fetchAll(PDO::FETCH_ASSOC); 拿到 $columns 之后,每个元素就是一条字段的完整档案。打印出来看看:
foreach ($columns as $col) { echo $col['COLUMN_NAME'] . ' | ' . $col['DATA_TYPE'] . ' | ' . $col['IS_NULLABLE'] . PHP_EOL; } 输出大概长这样:
id | int | NO username | varchar | NO email | varchar | YES created_at | datetime | YES 这里有个坑。有些环境里 INFORMATION_SCHEMA 查询会慢,特别是表特别多的时候。如果只是想要字段名列表,不关心类型和注释,用 DESCRIBE testtable 更快:
$stmt = $pdo->query('DESCRIBE testtable'); $fields = $stmt->fetchAll(PDO::FETCH_COLUMN); print_r($fields); DESCRIBE 返回的列里第一列就是字段名,FETCH_COLUMN 直接抽出来,干净利落。但它给不了字段注释,Comment 字段在 MySQL 里经常是空的,除非建表时专门写了 COMMENT。
我自己的习惯是:日常快速看字段用 DESCRIBE,需要生成文档、做数据字典、或者写自动化脚本时,走 INFORMATION_SCHEMA。后者信息全,还能直接拼出建表语句的字段部分。
另一个容易忽略的点:ORDINAL_POSITION 排序。不按这个排,字段顺序可能和建表时不一致。有人觉得字段顺序无所谓,但做代码生成或者对比表结构时,顺序乱了会很烦。
如果不用 PDO,用 mysqli 也行,逻辑一样:
$mysqli = new mysqli('127.0.0.1', 'root', 'password', 'testdb'); $result = $mysqli->query("SHOW FULL COLUMNS FROM testtable"); while ($row = $result->fetch_assoc()) { echo $row['Field'] . ' - ' . $row['Type'] . ' - ' . $row['Comment'] . PHP_EOL; } SHOW FULL COLUMNS 比 DESCRIBE 多一个 Comment 列,信息量介于两者之间。我个人挺喜欢这个命令,写起来短,返回的字段也够用。
实际项目里,我遇到过一次字段名带反引号的情况。表里有个字段叫 order,是 MySQL 保留字。用 INFORMATION_SCHEMA 查出来没问题,但后面拼接 SQL 时必须加反引号,否则直接报语法错误。所以拿到字段列表只是第一步,怎么用才是关键。
还有编码问题。INFORMATION_SCHEMA 返回的字段注释如果包含中文,连接字符集不是 utf8mb4 的话会乱码。PDO 的 DSN 里记得带上 charset=utf8mb4,mysqli 则要 set_charset('utf8mb4')。
代码写到最后,其实就三件事:连库、查 INFORMATION_SCHEMA 或 SHOW FULL COLUMNS、遍历输出。没有多复杂,但细节决定能不能一次跑通。
友情链接