PHP项目怎么实现数据导入功能?

wen PHP项目 8

本文目录导读:

PHP项目怎么实现数据导入功能?

  1. CSV文件导入(最常用)
  2. Excel文件导入(使用PhpSpreadsheet)
  3. 大文件分片导入处理
  4. 完整的上传+导入流程示例
  5. 关键注意事项
  6. 高级功能建议

实现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并添加完整的错误处理和进度跟踪功能。

抱歉,评论功能暂时关闭!