add stream parser
Questo commit è contenuto in:
parent
33e15895d3
commit
9899e5bfbd
30
README.md
30
README.md
|
@ -3,12 +3,18 @@ CSV parser/generator
|
|||
|
||||
<a href="https://phpci.gitnet.fr/build-status/view/2">![](https://phpci.gitnet.fr/build-status/image/2?branch=master&label=PHPCensor&style=flat-square)</a>
|
||||
|
||||
A simple PHP library to parse and generate CSV files.
|
||||
A simple PHP library to:
|
||||
|
||||
* parse a CSV file
|
||||
* parse a stream as CSV datas
|
||||
* generate CSV files.
|
||||
|
||||
PHP >= 7.1 required.
|
||||
|
||||
## Composer installation
|
||||
|
||||
```
|
||||
$ composer require deblan/csv "~2"
|
||||
$ composer require deblan/csv "~3"
|
||||
```
|
||||
|
||||
Or in your composer.json:
|
||||
|
@ -16,7 +22,7 @@ Or in your composer.json:
|
|||
```
|
||||
{
|
||||
"require": {
|
||||
"deblan/csv": "~2"
|
||||
"deblan/csv": "~3"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@ -67,7 +73,7 @@ $result = $csv->render('products.csv');
|
|||
$result = $csv->render('products.csv', FILE_APPEND);
|
||||
```
|
||||
|
||||
### Parser
|
||||
### Parse a file
|
||||
|
||||
```php
|
||||
use Deblan\Csv\CsvParser;
|
||||
|
@ -96,3 +102,19 @@ $csv->parseString($myString);
|
|||
$headers = $csv->getHeaders();
|
||||
$products = $csv->getDatas();
|
||||
```
|
||||
|
||||
### Parse a stram
|
||||
|
||||
```php
|
||||
use Deblan\Csv\CsvStreamParser;
|
||||
|
||||
// CsvStreamParser is a CsvParser
|
||||
$csv = new CsvStreamParser();
|
||||
|
||||
// Parse a stream
|
||||
$csv->parseStream(fopen('products.csv', 'r'));
|
||||
|
||||
while ($data = $csv->getData()) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
convertWarningsToExceptions = "true"
|
||||
processIsolation = "false"
|
||||
stopOnFailure = "false"
|
||||
syntaxCheck = "true"
|
||||
bootstrap = "vendor/autoload.php" >
|
||||
|
||||
<testsuites>
|
||||
|
|
69
src/Deblan/Csv/CsvStreamParser.php
File normale
69
src/Deblan/Csv/CsvStreamParser.php
File normale
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
namespace Deblan\Csv;
|
||||
|
||||
/**
|
||||
* class Csv.
|
||||
*
|
||||
* @author Simon Vieille <simon@deblan.fr>
|
||||
*/
|
||||
class CsvStreamParser extends CsvParser
|
||||
{
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
protected $resource;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $length;
|
||||
|
||||
/**
|
||||
* Parse a stream.
|
||||
*
|
||||
* @param resource $resource
|
||||
* @param int $length
|
||||
*/
|
||||
public function parseStream($resource, ? int $length = 0): void
|
||||
{
|
||||
if (!is_resource($resource)) {
|
||||
throw new \InvalidArgumentException('First argument must be a valid resource.');
|
||||
}
|
||||
|
||||
$this->resource = $resource;
|
||||
$this->length = $length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data of the stream parsing.
|
||||
*
|
||||
* @return null|array
|
||||
*/
|
||||
public function getData(): ? array
|
||||
{
|
||||
$csv = fgetcsv($this->resource, $this->length, $this->delimiter, $this->enclosure);
|
||||
|
||||
if ($csv === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$isHeaders = $this->hasHeaders && empty($this->headers);
|
||||
|
||||
if ($isHeaders) {
|
||||
$this->headers = $csv;
|
||||
|
||||
return $csv;
|
||||
}
|
||||
|
||||
if (!$isHeaders && $this->hasHeaders && !empty($this->headers)) {
|
||||
foreach ($this->headers as $key => $header) {
|
||||
$csv[$header] = isset($csv[$key]) ? $csv[$key] : null;
|
||||
}
|
||||
}
|
||||
|
||||
$this->datas[] = $csv;
|
||||
|
||||
return $csv;
|
||||
}
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
<?php
|
||||
|
||||
use Deblan\Csv\CsvParser;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class CsvParserParserTest extends \PHPUnit_Framework_TestCase
|
||||
class CsvParserTest extends TestCase
|
||||
{
|
||||
public function testGettersAndSettersAndDefaultValues()
|
||||
{
|
||||
|
|
176
tests/CsvStreamParserTest.php
File normale
176
tests/CsvStreamParserTest.php
File normale
|
@ -0,0 +1,176 @@
|
|||
<?php
|
||||
|
||||
use Deblan\Csv\CsvParser;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Deblan\Csv\CsvStreamParser;
|
||||
|
||||
class CsvParserParserTest extends CsvParserTest
|
||||
{
|
||||
public function testStreamParser()
|
||||
{
|
||||
$parser = new CsvStreamParser();
|
||||
$this->assertEquals([], $parser->getDatas());
|
||||
$this->assertEquals([], $parser->getHeaders());
|
||||
|
||||
$parser = new CsvStreamParser();
|
||||
$this->expectException('\InvalidArgumentException');
|
||||
$parser->parseStream(null);
|
||||
}
|
||||
|
||||
public function testStreamParser2()
|
||||
{
|
||||
$parser = new CsvStreamParser();
|
||||
$parser->setHasHeaders(true);
|
||||
|
||||
$parser->parseStream(fopen(__DIR__.'/fixtures/example.csv', 'r'));
|
||||
$this->assertEquals([], $parser->getDatas());
|
||||
$this->assertEquals([], $parser->getHeaders());
|
||||
|
||||
$this->assertEquals([
|
||||
'FOO',
|
||||
'BAR',
|
||||
], $parser->getData());
|
||||
$this->assertEquals([], $parser->getDatas());
|
||||
$this->assertEquals(['FOO', 'BAR'], $parser->getHeaders());
|
||||
|
||||
$this->assertEquals([
|
||||
'foo 1',
|
||||
'bar 1',
|
||||
'FOO' => 'foo 1',
|
||||
'BAR' => 'bar 1',
|
||||
], $parser->getData());
|
||||
$this->assertEquals([
|
||||
[
|
||||
'foo 1',
|
||||
'bar 1',
|
||||
'FOO' => 'foo 1',
|
||||
'BAR' => 'bar 1',
|
||||
],
|
||||
], $parser->getDatas());
|
||||
$this->assertEquals(['FOO', 'BAR'], $parser->getHeaders());
|
||||
|
||||
$parser->getData();
|
||||
$this->assertEquals([
|
||||
[
|
||||
'foo 1',
|
||||
'bar 1',
|
||||
'FOO' => 'foo 1',
|
||||
'BAR' => 'bar 1',
|
||||
],
|
||||
[
|
||||
'foo 2',
|
||||
'bar 2',
|
||||
'FOO' => 'foo 2',
|
||||
'BAR' => 'bar 2',
|
||||
],
|
||||
], $parser->getDatas());
|
||||
$this->assertEquals(['FOO', 'BAR'], $parser->getHeaders());
|
||||
|
||||
$parser->getData();
|
||||
$this->assertEquals([
|
||||
[
|
||||
'foo 1',
|
||||
'bar 1',
|
||||
'FOO' => 'foo 1',
|
||||
'BAR' => 'bar 1',
|
||||
],
|
||||
[
|
||||
'foo 2',
|
||||
'bar 2',
|
||||
'FOO' => 'foo 2',
|
||||
'BAR' => 'bar 2',
|
||||
],
|
||||
[
|
||||
'foo 3',
|
||||
'bar 3',
|
||||
'FOO' => 'foo 3',
|
||||
'BAR' => 'bar 3',
|
||||
],
|
||||
], $parser->getDatas());
|
||||
$this->assertEquals(['FOO', 'BAR'], $parser->getHeaders());
|
||||
}
|
||||
|
||||
public function testStreamParser3()
|
||||
{
|
||||
$parser = new CsvStreamParser();
|
||||
$parser->setHasHeaders(false);
|
||||
|
||||
$parser->parseStream(fopen(__DIR__.'/fixtures/example.csv', 'r'));
|
||||
$this->assertEquals([], $parser->getDatas());
|
||||
$this->assertEquals([], $parser->getHeaders());
|
||||
|
||||
$this->assertEquals([
|
||||
'FOO',
|
||||
'BAR'
|
||||
], $parser->getData());
|
||||
$this->assertEquals([
|
||||
[
|
||||
'FOO',
|
||||
'BAR'
|
||||
]
|
||||
], $parser->getDatas());
|
||||
$this->assertEquals([], $parser->getHeaders());
|
||||
|
||||
$this->assertEquals([
|
||||
'foo 1',
|
||||
'bar 1',
|
||||
], $parser->getData());
|
||||
$this->assertEquals([
|
||||
[
|
||||
'FOO',
|
||||
'BAR',
|
||||
],
|
||||
[
|
||||
'foo 1',
|
||||
'bar 1',
|
||||
],
|
||||
], $parser->getDatas());
|
||||
$this->assertEquals([], $parser->getHeaders());
|
||||
|
||||
$this->assertEquals([
|
||||
'foo 2',
|
||||
'bar 2',
|
||||
], $parser->getData());
|
||||
$this->assertEquals([
|
||||
[
|
||||
'FOO',
|
||||
'BAR',
|
||||
],
|
||||
[
|
||||
'foo 1',
|
||||
'bar 1',
|
||||
],
|
||||
[
|
||||
'foo 2',
|
||||
'bar 2',
|
||||
],
|
||||
], $parser->getDatas());
|
||||
$this->assertEquals([], $parser->getHeaders());
|
||||
|
||||
$this->assertEquals([
|
||||
'foo 3',
|
||||
'bar 3',
|
||||
], $parser->getData());
|
||||
$this->assertEquals([
|
||||
[
|
||||
'FOO',
|
||||
'BAR',
|
||||
],
|
||||
[
|
||||
'foo 1',
|
||||
'bar 1',
|
||||
],
|
||||
[
|
||||
'foo 2',
|
||||
'bar 2',
|
||||
],
|
||||
[
|
||||
'foo 3',
|
||||
'bar 3',
|
||||
],
|
||||
], $parser->getDatas());
|
||||
$this->assertEquals([], $parser->getHeaders());
|
||||
|
||||
$this->assertEquals(null, $parser->getData());
|
||||
}
|
||||
}
|
Caricamento…
Crea riferimento in una nuova segnalazione