0

0

使用PHP和PDO将CSV文件导入MySQL数据库的教程

DDD

DDD

发布时间:2025-07-15 20:34:01

|

1016人浏览过

|

来源于php中文网

原创

使用PHP和PDO将CSV文件导入MySQL数据库的教程

本教程详细介绍了如何使用PHP的PDO扩展将CSV文件高效、安全地导入MySQL数据库。文章着重解决了在导入过程中常见的SQL语法错误和CSV文件解析问题,特别是PDO预处理语句中参数占位符的正确使用,以及fgetcsv函数处理不同CSV分隔符的方法。通过提供完整代码示例和最佳实践,旨在帮助开发者避免常见陷阱,确保数据导入的准确性和系统稳定性。

1. 理解CSV文件导入需求

在web应用开发中,从csv文件导入数据到数据库是常见的需求。csv(comma separated values)文件以纯文本形式存储表格数据,每行记录由逗号或其他特定字符分隔。本教程将以一个包含两列数据的csv文件为例,演示如何将其导入到mysql数据库的users表中。

示例CSV数据格式:

BGYR002217;FK-066
BGYR002218;FK-140

注意,此示例中数据字段的分隔符是分号(;),而非默认的逗号(,)。

2. 核心技术栈

  • PHP: 服务器端脚本语言,用于处理文件上传和数据库交互。
  • PDO (PHP Data Objects): PHP的数据库抽象层,提供统一的API访问多种数据库,支持预处理语句,增强安全性和性能。
  • MySQL/MariaDB: 关系型数据库管理系统,用于存储数据。

3. 构建数据库表结构

首先,我们需要在MySQL数据库中创建一个用于存储CSV数据的表。假设表名为users,包含szam和forras_szam两列。

CREATE TABLE `users` (
    `id` INT AUTO_INCREMENT PRIMARY KEY,
    `szam` VARCHAR(255) NOT NULL,
    `forras_szam` VARCHAR(255) NOT NULL
);

4. PHP文件上传与解析

为了导入CSV文件,通常需要一个HTML表单供用户上传文件,然后PHP脚本接收并处理该文件。

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

4.1 HTML文件上传表单

创建一个简单的HTML文件(例如 index.html)来提供文件上传功能:

m18麦考林整站 for Ecshop
m18麦考林整站 for Ecshop

m18麦考林整站 for Ecshop v2.7.3 安装方法: 1,解压rar包上传到网站根目录 2,导入sql数据库文件,到你的数据库里,可以phpmyadmin等软件 3,修改data里config.php里面的数据库 用户名 密码等信息 为你自己的数据库信息 4,安装完毕之后的后台用户名密码为: 后台地址:域名/admin 用户名:admin 密码:admin123 模板使用教程: htt

下载



    
    CSV文件导入


    

上传CSV文件到MySQL

4.2 PHP处理脚本 (import.php)

这是核心的PHP脚本,负责数据库连接、CSV文件读取、解析和数据插入。

 PDO::ERRMODE_EXCEPTION, // 错误报告模式:抛出异常
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,       // 默认获取模式:关联数组
            PDO::ATTR_EMULATE_PREPARES   => false                   // 禁用模拟预处理,使用原生预处理
        ]
    );
} catch (PDOException $ex) {
    exit("数据库连接失败: " . $ex->getMessage());
}

// 3. 检查文件上传
if (!isset($_FILES["upcsv"]) || $_FILES["upcsv"]["error"] !== UPLOAD_ERR_OK) {
    exit("文件上传失败或未选择文件。错误码: " . ($_FILES["upcsv"]["error"] ?? 'N/A'));
}

$tmpFilePath = $_FILES["upcsv"]["tmp_name"];
if (!is_uploaded_file($tmpFilePath)) {
    exit("无效的文件上传。");
}

// 4. 打开并读取CSV文件
// 注意:fgetcsv 默认分隔符是逗号(,), 如果CSV文件使用分号(;)作为分隔符,需要明确指定
$fh = fopen($tmpFilePath, "r");
if ($fh === false) {
    exit("无法打开上传的CSV文件。");
}

// 准备SQL插入语句,使用正确的PDO占位符 `?`
// 错误示例:VALUES (?;?)
// 正确示例:VALUES (?,?)
$stmt = $pdo->prepare("INSERT INTO users (szam, forras_szam) VALUES (?, ?)");

$importedRows = 0;
while (($row = fgetcsv($fh, 0, ';')) !== false) { // 明确指定分号作为分隔符
    // 检查行数据是否有效,防止空行或格式不符的行导致错误
    if (count($row) < 2) {
        echo "跳过无效行: " . implode(';', $row) . "
"; continue; } try { // 执行预处理语句,绑定CSV行数据到占位符 $stmt->execute([$row[0], $row[1]]); $importedRows++; } catch (PDOException $ex) { // 捕获并输出每行导入的错误信息,而不是中断整个过程 echo "导入行错误: " . implode(';', $row) . " - " . $ex->getMessage() . "
"; } } // 5. 关闭文件句柄 fclose($fh); echo "导入完成!成功导入 " . $importedRows . " 行数据。"; ?>

5. 关键点解析与常见问题解决

5.1 PDO占位符的正确使用

原始问题中出现的错误 SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax;... VALUES (?;?) 明确指出SQL语法错误。

问题根源: PDO预处理语句中,参数占位符只能是问号(?)或具名参数(例如:param_name)。将分号(;)用作占位符是错误的语法。分号在SQL中通常用作语句的终止符,而不是参数绑定符号。

解决方案: 将SQL语句中的 VALUES (?;?) 改为 VALUES (?,?)。

// 错误示例:
// $stmt = $pdo->prepare("INSERT INTO users (szam, forras_szam) VALUES (?;?)");

// 正确示例:
$stmt = $pdo->prepare("INSERT INTO users (szam, forras_szam) VALUES (?, ?)");

5.2 fgetcsv函数与CSV分隔符

原始CSV数据 BGYR002217;FK-066 使用分号作为字段分隔符。fgetcsv函数默认使用逗号(,)作为分隔符。如果CSV文件使用其他字符作为分隔符,必须在fgetcsv函数的第三个参数中明确指定。

问题根源: 如果未指定分隔符,fgetcsv会将 BGYR002217;FK-066 视为单个字段读取到 $row[0] 中,导致 $row[1] 未定义,从而引发 Undefined array key 1 警告,并最终导致 execute 方法参数不足或不正确。

解决方案: 在调用 fgetcsv 时,将分隔符参数设置为分号(;):

// 错误示例(如果CSV使用分号分隔):
// while (($row = fgetcsv($fh)) !== false) { ... }

// 正确示例:
while (($row = fgetcsv($fh, 0, ';')) !== false) { // 0表示最大行长度不限制,';'是分隔符
    // ...
}

5.3 错误处理与健壮性

在实际应用中,对文件操作和数据库操作进行适当的错误处理至关重要。

  • 文件上传错误: 使用 $_FILES["upcsv"]["error"] 检查上传状态,并使用 is_uploaded_file() 确保文件是通过HTTP POST上传的。
  • 文件打开错误: 检查 fopen() 的返回值是否为 false。
  • PDO连接错误: 使用 try-catch 块捕获 PDOException。
  • PDO执行错误: 在循环内部,为每次 execute() 调用添加 try-catch 块,这样即使某一行数据导入失败,也不会中断整个导入过程,可以记录错误并继续处理下一行。
  • 数据有效性检查: 在处理 $row 数组之前,检查 count($row) 以确保行数据包含预期的列数,避免 Undefined array key 错误。

6. 最佳实践与注意事项

  • 使用预处理语句: 始终使用PDO预处理语句来插入或更新数据,这可以有效防止SQL注入攻击,并提高重复执行相同SQL语句的性能。
  • 明确字符集: 在PDO连接字符串中指定charset(例如utf8mb4),并确保数据库、表和列的字符集也一致,以避免乱码问题。
  • 错误报告: 在开发环境中,将PDO::ATTR_ERRMODE设置为PDO::ERRMODE_EXCEPTION,以便在出现数据库错误时抛出异常,方便调试。在生产环境中,可以考虑将错误记录到日志文件而非直接输出给用户。
  • 处理大文件: 对于非常大的CSV文件,逐行读取并插入可能会导致性能问题或内存耗尽。可以考虑以下优化:
    • 事务处理: 每隔N行提交一次事务,减少数据库操作的开销。
    • LOAD DATA INFILE: 如果PHP脚本和MySQL服务器在同一台机器上,并且有文件系统权限,LOAD DATA INFILE是导入大量数据最快的方法。
    • 分块读取: 如果内存是瓶颈,可以分块读取CSV文件。
  • 用户体验: 对于长时间运行的导入任务,考虑在前端显示进度条,或使用AJAX异步处理,避免页面超时。

7. 总结

通过本教程,我们学习了如何使用PHP和PDO将CSV文件导入MySQL数据库。核心要点包括:正确使用PDO预处理语句的占位符(?),以及根据CSV文件的实际分隔符配置fgetcsv函数。同时,强调了错误处理、健壮性设计和性能优化在数据导入过程中的重要性。遵循这些指导原则,将能够构建出高效、安全且稳定的CSV数据导入功能。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

727

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

327

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

350

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

1242

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

360

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

820

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

581

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

423

2024.04.29

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

158

2026.01.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MySQL 教程
MySQL 教程

共48课时 | 2万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 812人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号