php实现班级通信录怎么导入压缩包_php解压后导入文件【步骤】

5次阅读

php安全解压用户上传ZIP需校验文件名防路径遍历,创建临时目录并限制扩展名;读取csv/excel前统一转UTF-8、清理bom;导入前校验字段、去重、分批插入;用pdo事务+错误报告确保数据准确。

php实现班级通信录怎么导入压缩包_php解压后导入文件【步骤】

PHP 怎么安全解压用户上传的 zip 压缩包

不能直接用 exec('unzip') 或盲目信任 ZipArchive::extractTo() 的目标路径,否则容易被路径遍历攻击(比如压缩包里含 ../../../etc/passwd)。必须校验每个文件名是否合法、是否在预期目录内。

实操建议:

立即学习PHP免费学习笔记(深入)”;

  • ZipArchive 打开后,遍历所有文件,对每个 $zip->getNameIndex($i) 调用 basename() + realpath() 双重校验,确保不含 .. 且不越出解压根目录
  • 解压前先创建唯一临时目录(如 sys_get_temp_dir() . '/import_' . uniqid()),并设好权限(0700
  • 跳过以 . 开头的文件(如 .DS_Store)和非 .csv / .xlsx 文件(按业务限定)

怎么识别并读取解压后的通讯录文件(CSV / Excel)

班级通信录常见格式是 CSV 或 Excel(.xlsx),PHP 默认不支持读取 Excel,需依赖第三方库;而 CSV 可用原生 fgetcsv(),但要注意编码(常见 GBK/UTF-8 混用)。

实操建议:

立即学习PHP免费学习笔记(深入)”;

  • 检测文件扩展名后,用 mb_detect_encoding(file_get_contents($file), ['UTF-8', 'GBK', 'BIG5'], true) 初步判断编码,再用 mb_convert_encoding() 统一转为 UTF-8
  • 读 CSV 时,用 fopen($file, 'r') + fgetcsv(),并设置 ini_set('auto_detect_line_endings', 1) 兼容 windows/mac 换行
  • 读 Excel 推荐 phpspreadsheet:用 IOFactory::load($file),再取 $sheet->toArray();注意限制最大行数(如 $reader->setReadDataOnly(true) 防内存溢出)

导入前怎么校验数据格式和关键字段

直接入库会因空值、重复学号、非法手机号导致失败或脏数据。校验必须在解压+读取之后、INSERT 之前完成。

实操建议:

立即学习PHP免费学习笔记(深入)”;

  • 定义必填字段白名单,如 ['student_id', 'name', 'class', 'phone'],检查每行是否缺失;用 filter_var($phone, FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '/^1[3-9]d{9}$/']]) 校验手机号
  • 去重逻辑放在 PHP 层:用 array_unique($data, SORT_REGULAR) 不够,应按 student_id 做键去重($unique[$row['student_id']] = $row
  • 批量插入前,用 array_chunk($cleaned_data, 100) 分批,避免单次 sql 过长或超时

怎么把校验后的数据写入 mysql 并反馈结果

不能用一条 INSERT ... VALUES (...), (...) 硬塞全部数据——失败时无法定位哪一行错;也不能每行都执行一次 INSERT——太慢且易锁表。

实操建议:

立即学习PHP免费学习笔记(深入)”;

  • 用 PDO 预处理语句 + beginTransaction() 包裹整个导入过程,出错则 rollback();成功后记录日志(如 “导入 42 行,跳过 3 行重复学号”)
  • 构建错误报告数组:对每一行,存 ['row' => 5, 'error' => '手机号格式错误'],最后 jsON 返回给前端展示
  • 特别注意:如果表有唯一索引(如 student_id),用 INSERT ... ON DUPLICATE KEY UPDATE 替代先查后插,但得明确冲突时是忽略还是覆盖

真正麻烦的不是解压或读取,而是用户上传的文件里藏着 BOM 头、混合编码、Excel 公式残留、隐藏列——这些不会报错,但会导致字段错位或空值入库。每次导入前,强制做 trim() + str_replace("x{FEFF}", '', $str) 清理 BOM,比事后 debug 快得多。

text=ZqhQzanResources