一个高性能php CSV读取库

最近因为项目需要读取大量的CSV数据,所以开发了这么一个库,这个库最大的优点就是:单文件无依赖、高性能、低内存占用同时解决了中文字符编码的问题

此库基于PHP7.3.33编写,最低版本要求7.1.0,同时兼容PHP8。

首先来看下基本用法,composer安装不解释

ShellScript
composer require lantongxue/csv-reader

创建一个CSVReader,CSVReader一共三个构造参数

PHP
/**
 * @param string $csvFile
 * @param bool $firstRowIsHeader 是否将第一行设置为头部
 * @param array $getcsvParams 设置fgetcsv函数的参数,主要是为了兼容PHP8的改动, 
 * 默认如下
 *  [
 *     'separator' => ",",
 *     'enclosure' => "\"",
 *     'escape' => "\\",
 *  ];
 */
CSVReader(string $csvFile, bool $firstRowIsHeader = true, array $getcsvParams = [])

第一种用法,通过迭代器遍历数据,CSVReader实现了内建迭代器(Iterator)接口,所以可以直接用foreach进行遍历

PHP
$csv = 'test.csv';
$reader = new lantongxue\CSVReader($csv);
foreach($reader as $row) {
    // todo
}

第二种用法,分块读取,CSVReader支持分块读取数据,同时可以指定每次读取多少条数据

PHP
$csv = 'test.csv';
$reader = new lantongxue\CSVReader($csv);
$reader->Chunk(function($rows) {
    foreach($rows as $row) {
        // todo
    }
    return true;
}, 1000);

Chunk方法两个参数,第一个是回调函数,传入一个读取的数据行,第二个参数是每次读取多少行。

具体用法就是上面两种,下面我们来简单说下实现原理

和其他库不同的是,CSVReader处理数据的时候并没有一次性将数据读入内存中,而是通过指针读取,同时实现迭代器(Iterator)接口,实现按需获取数据。

其核心本质也是通过调用fgetcsv函数实现,记录每次读取后的偏移位置,甚至可以实现“续读”功能(注:此版本未实现该功能)。

解决中文编码问题,这个问题我测试的结果是:在Windows 10专业版上面,PHP8以下就会有中文错位的问题,而PHP8以上则不会。通过查阅文档得知:fgetcsv函数受系统常量LC_CTYPE影响,可能会错误的解析某些单字节编码的数据。

解决办法:设置地区语言及编码。

PHP
setlocale(LC_CTYPE, 'zh-CN.UTF-8'); // Windows 系统这样设置
setlocale(LC_CTYPE, 'zh_CN.UTF-8'); // Linux 系统这样设置

这样就解决了中文错位的问题。

GitHub:https://github.com/lantongxue/php-csv-reader

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注