offdev / csv
使用流读取、解析和验证CSV文件
1.2.2
2019-03-21 14:50 UTC
Requires
- php: >=7.2
- illuminate/support: ^5.6
- illuminate/validation: ^5.6
- psr/http-message: ^1.0
Requires (Dev)
- infection/infection: ^0.10.5
- localheinz/phpstan-rules: ^0.7.1
- phpstan/phpstan: ^0.11.1
- phpunit/phpunit: ^7.0
- squizlabs/php_codesniffer: ^3.0
README
需求
- PHP >= 7.2
- Composer
安装
$ composer require offdev/csv
介绍
这个解析器被编写出来,以便以简单方便的方式解析来自几乎任何数据源的大CSV文件。它还提供了验证CSV源中每个记录的可能性。
为了让解析器工作,您需要向其提供数据。这些数据将以流的形式表示。这使我们能够处理大量数据。解析器还可以处理HTTP流。
请继续阅读以了解其使用方法。
流
为了向解析器提供数据,您需要给它一个流。流可以通过多种方式获得
使用资源
use Offdev\Csv\Stream; $stream = Stream::factory(fopen('/path/to/file.csv', 'r'));
使用字符串
use Offdev\Csv\Stream; $stream = Stream::factory('this string will be transformed to an in-memory stream');
注意:此方法也适用于实现了 __toString 方法的任何对象。
使用HTTP流(参见 PSR-7/Streams)
use GuzzleHttp\Client; use Offdev\Csv\Stream; $client = new Client(); $response = $client->get('http://httpbin.org/get'); $stream = Stream::factory($response->getBody());
便利性
如果您想快速创建一个流,可以使用提供的辅助函数。您需要使用composer的自动加载器才能使用此功能。
// Recognizes files, and opens them in read mode $fileStream = stream('/tmp/results.csv'); // Create from string $stringStream = stream('stream content'); // From objcets, which implement the __toString method class Example { public function __toString(){ return 'some example'; } } $objectToStringStream = stream(new Example());
解析器
基础知识
一旦解析器有一个流可以工作,我们就可以开始使用它
use Offdev\Csv\Parser; $parser = new Parser($stream); while (!$parser->eof()) { $record = $parser->readLine(); echo $record->get('header-column2').PHP_EOL; }
上面的示例生成了以下输出
$ php example.php
row1-value2
row2-value2
为了方便,解析器也可以用作迭代器
$parser = new Parser($stream); foreach ($parser as $index => $record) { echo $record->get('header-column2').PHP_EOL; }
这将产生与上面示例相同的输出。
选项
解析器接受许多选项。解析器接受数组中的选项,该数组作为构造函数的第二个参数传递
$parser = new Parser($stream, [ Parser::OPTION_DELIMITER => ';' ]);
选项完整列表
处理器
为了提高可用性和关注点的分离,解析器接受一个处理器,该处理器将接收来自流的任何解析记录。记录表示为 Laravel 集合。
如果为解析器分配了验证器,则有效和无效的记录将传递到相应的方法。如果没有提供验证器,则所有记录都将传递到 parseRecord 方法。空行始终被忽略。
示例处理器
namespace MyCompany\ProjectX\Processors; use Offdev\Csv\Item; use Offdev\Csv\ProcessorInterface; class MyProcessor implements ProcessorInterface { public function processRecord(Item $record): void { // No header in CSV, use numeric index echo "Got item: ".$record->get(1).PHP_EOL; } public function processInvalidRecord(Item $record): void { $this->processRecord($record); } public function eof(): void { echo "---EOF---".PHP_EOL; } }
用法
use MyCompany\ProjectX\Processors\MyProcessor; use Offdev\Csv\Parser; use Offdev\Csv\Stream; $stream = Stream::factory("1;John\n2;Lisa\n3;Robert"); $parser = new Parser($stream, [ Parser::OPTION_DELIMITER => ';', Parser::OPTION_HEADER => false ]); $parser->setProcessor(new MyProcessor()); $parser->run();
上面的示例生成了以下输出
$ php example.php
Got item: John
Got item: Lisa
Got item: Robert
---EOF---
验证器
现在,大多数时候,我们希望确保CSV中包含的数据符合给定的格式。此软件包使用Laravel验证软件包来为CSV的内容提供规则引擎。所有规则的全列表可以在此找到。
用法
use Offdev\Csv\Parser; use Offdev\Csv\Stream; use Offdev\Csv\Validator; try { $stream = Stream::factory("id,name\n1,John\n2,Lisa\nNaN,Robert"); $parser = new Parser($stream); $parser->setValidator(new Validator([ 'id' => 'required|numeric', 'name' => 'required|string|min:3' ])); $parser->run(); echo "CSV is valid!".PHP_EOL; } catch (\Exception $e) { echo "CSV is invalid!".PHP_EOL; }
代码质量
首先,通过运行 composer install 安装依赖项。您还需要确保启用xdebug,以便PHPUnit生成代码覆盖率。
PHP Code Sniffer
$ ./vendor/bin/phpcs --colors --standard=PSR2 -v src/ tests/
Registering sniffs in the PSR2 standard... DONE (42 sniffs registered)
Creating file list... DONE (10 files in queue)
Changing into directory /Users/pascal/devel/csv-parser/src
Processing Validator.php [PHP => 436 tokens in 74 lines]... DONE in 46ms (0 errors, 0 warnings)
Processing Parser.php [PHP => 2125 tokens in 312 lines]... DONE in 140ms (0 errors, 0 warnings)
Processing Stream.php [PHP => 2248 tokens in 344 lines]... DONE in 116ms (0 errors, 0 warnings)
Processing ParserInterface.php [PHP => 552 tokens in 115 lines]... DONE in 27ms (0 errors, 0 warnings)
Processing ProcessorInterface.php [PHP => 168 tokens in 36 lines]... DONE in 21ms (0 errors, 0 warnings)
Changing into directory /Users/pascal/devel/csv-parser/tests
Processing ParserTest.php [PHP => 1797 tokens in 214 lines]... DONE in 149ms (0 errors, 0 warnings)
Processing TestProcessor.php [PHP => 427 tokens in 80 lines]... DONE in 31ms (0 errors, 0 warnings)
Processing ValidatorTest.php [PHP => 179 tokens in 33 lines]... DONE in 14ms (0 errors, 0 warnings)
Processing StreamTest.php [PHP => 1647 tokens in 217 lines]... DONE in 124ms (0 errors, 0 warnings)
Processing InvalidStream.php [PHP => 999 tokens in 210 lines]... DONE in 57ms (0 errors, 0 warnings)
PHPUnit
$ ./vendor/bin/phpunit
PHPUnit 7.4.0 by Sebastian Bergmann and contributors.
...................................... 38 / 38 (100%)
Time: 1.71 seconds, Memory: 8.00MB
OK (38 tests, 66 assertions)
Generating code coverage report in HTML format ... done
Code Coverage Report:
2018-10-14 08:42:12
Summary:
Classes: 100.00% (3/3)
Methods: 100.00% (36/36)
Lines: 100.00% (150/150)
\Offdev\Csv::Offdev\Csv\Parser
Methods: 100.00% (15/15) Lines: 100.00% ( 76/ 76)
\Offdev\Csv::Offdev\Csv\Stream
Methods: 100.00% (19/19) Lines: 100.00% ( 67/ 67)
\Offdev\Csv::Offdev\Csv\Validator
Methods: 100.00% ( 2/ 2) Lines: 100.00% ( 7/ 7)
Infection
$ ./vendor/bin/infection
You are running Infection with xdebug enabled.
____ ____ __ _
/ _/___ / __/__ _____/ /_(_)___ ____
/ // __ \/ /_/ _ \/ ___/ __/ / __ \/ __ \
_/ // / / / __/ __/ /__/ /_/ / /_/ / / / /
/___/_/ /_/_/ \___/\___/\__/_/\____/_/ /_/
Running initial test suite...
PHPUnit version: 7.4.0
44 [============================] 2 secsProcessing source code files: 0/5
Generate mutants...
Processing source code files: 5/5
Creating mutated files and processes: 89/89
.: killed, M: escaped, S: uncovered, E: fatal error, T: timed out
E.E...M..EEEM.EE.EEE.E.......E.................... (50 / 89)
...........E........................... (89 / 89)
89 mutations were generated:
74 mutants were killed
0 mutants were not covered by tests
2 covered mutants were not detected
13 errors were encountered
0 time outs were encountered
Metrics:
Mutation Score Indicator (MSI): 97%
Mutation Code Coverage: 100%
Covered Code MSI: 97%
Please note that some mutants will inevitably be harmless (i.e. false positives).
Dashboard report has not been sent: it is not a Travis CI
Time: 17s. Memory: 14.00MB