PHP将指定文件夹下多csv文件[即多表]导入到sqlite单文件

支持多表,中文字段,csv文件utf-8编码 逗号分隔,第一行字段以后一行一条内容

php 复制代码
<?php

class CsvToSqlite {
    private $db;
    private $csvDir;
    private $sqliteFile;
    public function __construct($csvDir, $sqliteFile) {
        $this->csvDir = rtrim($csvDir, '/');
        $this->sqliteFile = $sqliteFile;
        try {
            $this->db = new PDO("sqlite:{$this->sqliteFile}");
            $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (PDOException $e) {
            die("数据库连接失败: " . $e->getMessage());
        }
    }
    public function convert() {
        $csvFiles = glob($this->csvDir . '/*.csv');        
        foreach ($csvFiles as $csvFile) {
            $this->processCsvFile($csvFile);
        }        
        echo "所有CSV文件处理完成!\n";
    }
    private function processCsvFile($csvFile) {
        $tableName = pathinfo($csvFile, PATHINFO_FILENAME);
        echo "正在处理文件: {$csvFile}\n";        
        try {
            $handle = fopen($csvFile, 'r');
            if ($handle === false) throw new Exception("无法打开文件: {$csvFile}");
            $headers = fgetcsv($handle);
            if ($headers === false) throw new Exception("CSV文件为空: {$csvFile}");
            $this->createTable($tableName, $headers);
            $placeholders = str_repeat('?,', count($headers) - 1) . '?';
            $sql = "INSERT INTO {$tableName} VALUES ($placeholders)";
            $stmt = $this->db->prepare($sql);
            $this->db->beginTransaction();
            while (($row = fgetcsv($handle)) !== false) {
                if (count($row) === count($headers)) {
                    try {
                        $stmt->execute($row);
                    } catch (PDOException $e) {
                        echo "插入数据失败: " . $e->getMessage() . "\n";
                        continue;
                    }
                }
            }
            $this->db->commit();            
            fclose($handle);
            echo "表 {$tableName} 创建并导入完成\n";            
        } catch (Exception $e) {
            if ($this->db->inTransaction()) {
                $this->db->rollBack();
            }
            echo "处理文件 {$csvFile} 时出错: " . $e->getMessage() . "\n";
        }
    }
    private function createTable($tableName, $headers) {
        $tableName = $this->sanitizeIdentifier($tableName);
        $columns = array_map([$this, 'sanitizeIdentifier'], $headers);
        $columnDefs = array_map(function($col) {
            return "{$col} TEXT";
        }, $columns);        
        $sql = "CREATE TABLE IF NOT EXISTS {$tableName} (" . 
               implode(', ', $columnDefs) . ")";        
        try {
            $this->db->exec($sql);
            $this->db->exec("DELETE FROM {$tableName}");
        } catch (PDOException $e) {
            throw new Exception("创建表失败: $sql@" . $e->getMessage());
        }
    }
    private function sanitizeIdentifier($identifier) {
        $safe = preg_replace('/[^\w\x{4e00}-\x{9fa5}]+/u', '_', $identifier);
        if (is_numeric($safe[0])) { $safe = 'col_' . $safe;}
        return Trim($safe,"_");
    }
    public function getTableRowCount($tableName) {
        $tableName = $this->sanitizeIdentifier($tableName);
        $stmt = $this->db->query("SELECT COUNT(*) FROM {$tableName}");
        return $stmt->fetchColumn();
    }
    public function __destruct() {
        $this->db = null;
    }
}

// 使用示例
try {
    $csvDir = './csv_files';
    $sqliteFile = './database.sqlite';    
    $converter = new CsvToSqlite($csvDir, $sqliteFile);    
    $converter->convert();    
} catch (Exception $e) {
    echo "发生错误: " . $e->getMessage() . "\n";
}
?>
相关推荐
许彰午14 小时前
# allbytaskid——一个接口扛六个DataStore
运维·服务器·php
淡海水18 小时前
01-07-运行时-GC深度剖析-内存分配回收与结构选择
jvm·windows·unity·gc
小白勇闯网安圈20 小时前
Django Form 组件详解:从表单生成到 ModelForm 数据校验
数据库·django·sqlite
sbjdhjd20 小时前
企业站 SQL 注入实战:PCRE 正则回溯绕过关键词 WAF 完整实战 | 进阶02
sql·安全·web安全·网络安全·ai·开源·php
2602_9599609221 小时前
电商大厂Java面试:从Spring Boot、JPA、微服务到Redis、Kafka、Spring Security与监控,谢飞机的爆笑三轮问答
java·jvm·spring boot·redis·面试题
weixin_BYSJ198721 小时前
springboot技能与工具共享小程序---附源码29657
java·javascript·spring boot·python·小程序·django·php
张小姐的猫21 小时前
【Linux】网络编程 —— 传输层协议 TCP(下)
linux·运维·服务器·网络·tcp/ip·http·php
weixin_BYSJ198721 小时前
flask民族服饰饰品商城小程序---附源码37399
java·javascript·spring boot·python·小程序·django·php
一水21 小时前
AI 时代审查思维:审查第一篇
java·jvm·数据库·spring
それども1 天前
JVM MetaspaceSize 参数作用
jvm