txt导入失败主因是格式不统一:须用UTF-8无bom编码、制表符t分隔、首行为字段名;推荐str_getcsv()解析,注意字段名严格匹配及分批事务入库。

txt 文件格式必须先统一字段分隔符
班级通信录的 txt 导入失败,八成卡在格式不一致上。php 不会自动猜你用的是逗号、制表符还是空格分隔——fgetcsv() 默认按逗号,file() + explode() 则完全依赖你手动指定分隔符。
实操建议:
- 要求原始 txt 用制表符
t分隔(比空格和逗号更安全,姓名里常含逗号,空格易被误删) - 首行必须是字段名,例如:
学号t姓名t电话t邮箱 - 保存 txt 时选「UTF-8 无 BOM」编码,否则中文读出来是乱码或开头多出
 - 用
hexdump -C your.txt | head(linux/macOS)或编辑器十六进制视图确认 BOM 是否存在
用 str_getcsv() 解析每行比 fgetcsv() 更可控
fgetcsv() 对制表符支持弱,且默认跳过空行、处理引号逻辑复杂;而 str_getcsv() 是纯字符串解析函数,传入行内容和分隔符即可,适合 txt 这类简单结构。
示例关键片段:
立即学习“PHP免费学习笔记(深入)”;
$lines = file('contacts.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $header = str_getcsv($lines[0], "t"); $data = []; for ($i = 1; $i < count($lines); $i++) { $row = str_getcsv($lines[$i], "t"); if (count($row) === count($header)) { $data[] = array_combine($header, $row); } }
注意点:
- 务必检查
count($row) === count($header),防某行少字段导致array_combine()报 Warning - 若 txt 含中文,
str_getcsv()在 PHP 5.6+ 默认支持 UTF-8,但旧版本需先mb_convert_encoding($line, 'UTF-8', 'auto') - 别用
explode("t", $line)—— 若姓名含制表符(极少见但可能),会错切字段
导入前必须做字段清洗和类型校验
txt 是纯文本,没有 schema 约束。直接插入数据库前,不清理会导致手机号存成 "138-1234-5678"、邮箱缺失 @、学号带空格等脏数据。
基础清洗建议:
- 学号:用
trim()去首尾空格,再preg_replace('/D/', '', $id)剔除非数字(如“S2023001” → “2023001”) - 电话:保留数字和
+-(),再filter_var($phone, FILTER_SANITIZE_NUMBER_INT) - 邮箱:用
filter_var($email, FILTER_VALIDATE_EMAIL)校验,无效则设为NULL或跳过整行 - 姓名:强制
mb_substr(trim($name), 0, 20)截断,防超长写入数据库报错
批量插入数据库时避免逐行 INSERT
一个 50 人的 txt,如果循环执行 50 次 INSERT INTO ... VALUES (...),性能差且容易触发 mysql 连接超时。应聚合成单条多值语句。
示例(pdo 写法):
$placeholders = str_repeat('(?, ?, ?, ?),', count($data) - 1) . '(?, ?, ?, ?)'; $sql = "INSERT INTO students (student_id, name, phone, email) VALUES $placeholders"; $stmt = $pdo->prepare($sql); $values = []; foreach ($data as $row) { $values[] = $row['学号'] ?? ''; $values[] = $row['姓名'] ?? ''; $values[] = $row['电话'] ?? ''; $values[] = $row['邮箱'] ?? ''; } $stmt->execute($values);
注意:
- 字段名映射要明确,
$row['学号']中的键名必须与 txt 首行完全一致(包括全角/半角空格) - 若数据量超 1000 行,拆成每 500 行一批执行,防 SQL 语句过长或内存溢出
- 执行前加事务:
$pdo->beginTransaction(),成功后commit(),失败则rollback()
实际导入时最常被忽略的是 BOM 头和字段数对齐——这两处一错,整个数组就塌了,后面清洗和入库全是白忙。