本文目录导读:

实现PHP数据导入功能,通常需要以下几个关键步骤:获取数据源(如CSV、Excel或SQL文件)、解析数据、验证数据、最后将数据写入数据库。
下面我为你介绍几种常见的数据导入方案及详细代码示例。
CSV文件导入(最常用)
CSV导入是最简单、兼容性最好的方式。
<?php
// CSV导入函数
function importCSV($filePath, $tableName, $db) {
// 打开文件
if (($handle = fopen($filePath, "r")) !== FALSE) {
// 读取表头(第一行)
$headers = fgetcsv($handle);
// 准备SQL语句
$columns = implode(", ", $headers);
$placeholders = implode(", ", array_fill(0, count($headers), "?"));
$sql = "INSERT INTO $tableName ($columns) VALUES ($placeholders)";
$stmt = $db->prepare($sql);
// 逐行读取数据
$rowCount = 0;
while (($data = fgetcsv($handle)) !== FALSE) {
// 数据验证(示例)
if (empty($data[0]) || !is_numeric($data[2])) {
continue; // 跳过无效行
}
// 执行插入
$stmt->execute($data);
$rowCount++;
}
fclose($handle);
return "成功导入 $rowCount 行数据";
} else {
return "无法打开文件";
}
}
// 使用示例(文件上传后)
if ($_FILES['csv_file']['error'] == UPLOAD_ERR_OK) {
$tmpPath = $_FILES['csv_file']['tmp_name'];
$result = importCSV($tmpPath, 'users', $pdo);
echo $result;
}
?>
Excel文件导入(使用PhpSpreadsheet)
Excel导入需要安装第三方库,推荐使用PhpSpreadsheet。
安装
composer require phpoffice/phpspreadsheet
实现代码
<?php
require 'vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\IOFactory;
function importExcel($filePath, $tableName, $db) {
$spreadsheet = IOFactory::load($filePath);
$worksheet = $spreadsheet->getActiveSheet();
$rows = $worksheet->toArray();
// 提取表头
$headers = array_shift($rows);
// 验证表头
$expectedHeaders = ['姓名', '邮箱', '年龄']; // 你的预期表头
if ($headers != $expectedHeaders) {
return "表头格式不正确";
}
// 批量插入
$columns = implode(", ", $headers);
$placeholders = implode(", ", array_fill(0, count($headers), "?"));
$sql = "INSERT INTO $tableName ($columns) VALUES ($placeholders)";
$stmt = $db->prepare($sql);
$successCount = 0;
$errorCount = 0;
foreach ($rows as $rowIndex => $row) {
// 跳过空行
if (empty(array_filter($row))) continue;
try {
// 数据清理
$row = array_map('trim', $row);
// 验证邮箱格式
if (!filter_var($row[1], FILTER_VALIDATE_EMAIL)) {
$errorCount++;
continue;
}
$stmt->execute($row);
$successCount++;
} catch (Exception $e) {
$errorCount++;
// 记录错误日志
error_log("第 " . ($rowIndex + 2) . " 行导入失败: " . $e->getMessage());
}
}
return "成功导入 $successCount 条,失败 $errorCount 条";
}
?>
大文件分片导入处理
处理大文件时,建议分批导入避免超时。
<?php
function batchImportCSV($filePath, $tableName, $db, $batchSize = 1000) {
$handle = fopen($filePath, "r");
$headers = fgetcsv($handle);
$columns = implode(", ", $headers);
$placeholders = implode(", ", array_fill(0, count($headers), "?"));
$sql = "INSERT INTO $tableName ($columns) VALUES ($placeholders)";
$db->beginTransaction();
$stmt = $db->prepare($sql);
$batch = [];
$count = 0;
$totalCount = 0;
while (($data = fgetcsv($handle)) !== FALSE) {
$batch[] = $data;
$count++;
// 达到批次大小则执行插入
if ($count >= $batchSize) {
foreach ($batch as $row) {
$stmt->execute($row);
$totalCount++;
}
$db->commit();
$batch = [];
$count = 0;
$db->beginTransaction();
}
}
// 处理剩余数据
if (!empty($batch)) {
foreach ($batch as $row) {
$stmt->execute($row);
$totalCount++;
}
$db->commit();
}
fclose($handle);
return $totalCount;
}
?>
完整的上传+导入流程示例
<?php
// upload_and_import.php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$allowedTypes = ['text/csv', 'application/vnd.ms-excel',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'];
if (!in_array($_FILES['file']['type'], $allowedTypes)) {
die("不支持的文件类型");
}
// 限制文件大小 10MB
if ($_FILES['file']['size'] > 10 * 1024 * 1024) {
die("文件过大,最大支持10MB");
}
// 保存上传文件
$uploadDir = 'uploads/';
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
$filePath = $uploadDir . uniqid() . '_' . basename($_FILES['file']['name']);
move_uploaded_file($_FILES['file']['tmp_name'], $filePath);
try {
// 连接数据库
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', 'password');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 根据文件类型选择导入方式
$extension = pathinfo($filePath, PATHINFO_EXTENSION);
if ($extension === 'csv') {
$result = importCSV($filePath, 'users', $pdo);
} else {
$result = importExcel($filePath, 'users', $pdo);
}
echo "导入结果:$result";
// 清理临时文件
unlink($filePath);
} catch (Exception $e) {
echo "导入失败:" . $e->getMessage();
}
}
?>
<!-- HTML上传表单 -->
<form method="post" enctype="multipart/form-data">
<input type="file" name="file" accept=".csv,.xlsx,.xls" required>
<button type="submit">开始导入</button>
</form>
关键注意事项
安全性
- 文件类型验证:检查MIME类型和扩展名
- SQL注入防护:始终使用预处理语句
- 文件大小限制:防止服务器资源耗尽
- 验证:检查是否包含恶意代码
性能优化
- 使用事务:批量提交减少数据库I/O
- 分批处理:避免内存溢出
- 索引优化:确保导入表有合适索引
- 关闭自动提交:手动控制事务
数据验证
- 必填字段检查
- 数据类型验证
- 唯一性检查(邮箱、用户名等)
- 数据长度验证
错误处理
- 记录失败行号和原因
- 提供下载错误报告功能
- 支持断点续传(超大文件)
高级功能建议
// 导入进度跟踪(适用于AJAX异步导入)
function getImportProgress($jobId) {
// 使用Redis或文件记录当前进度
return [
'total' => 10000,
'processed' => 4500,
'percentage' => 45
];
}
// 数据映射功能(允许用户自定义字段映射)
// Excel的"联系方式"列映射到数据库的"phone"字段
$fieldMapping = [
'姓名' => 'username',
'邮箱' => 'email',
'联系方式' => 'phone'
];
根据你的具体需求(数据量大小、文件格式、实时性要求等),可以选择合适的方案,对于小型项目,CSV导入就足够;对于企业级应用,建议使用PhpSpreadsheet并添加完整的错误处理和进度跟踪功能。