1. Go to this page and download the library: Download voilab/csv library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
voilab / csv example snippets
$parser = new \voilab\csv\Parser($defaultOptions = []);
$result = $parser->fromString($str = "A;B\n1;test", $options = []);
// or
$result = $parser->fromFile($file = '/path/file.csv', $options = []);
// or with a raw resource (fopen, fsockopen, php://memory, etc)
$result = $parser->fromResource($resource, $options = []);
// or with an array or an Iterator interface
$result = $parser->fromIterable($array = [['A', 'B'], ['1', 'test']], $options = []);
// or with a SPL file object
$result = $parser->fromSplFile($object = new \SplFileObject('file.csv'), $options = []);
// or with a PSR stream interface (ex. HTTP response message body)
$response = $someHttpClient->request('GET', '/');
$result = $parser->fromStream($response->getBody(), $options = []);
// or with a custom \voilab\csv\CsvInterface implementation
$result => $parser->parse($myCsvInterface, $options = []);
$parser = new \voilab\csv\Parser([
'delimiter' => ';',
'columns' => [
'A' => function (string $data) {
return (int) $data;
},
'B' => function (string $data) {
return ucfirst($data);
}
]
]);
$csv = <<<CSV
A; B
4; hello
2; world
CSV;
$result = $parser->fromString($csv);
foreach ($result as $row) {
var_dump($row['A']); // int
var_dump($row['B']); // string with first capital letter
}
$parser->fromFile('file.csv', [
// fgetcsv
'delimiter' => ',',
'enclosure' => '"',
'escape' => '\\',
'length' => 0,
'autoDetectLn' => null,
// resources
'metadata' => [],
'close' => false,
// PSR stream
'lineEnding' => "\n",
// headers management
'headers' => true,
'strict' => false,
'serLineEnding(),
'guessEncoding' => new \voilab\csv\GuesserEncoding(),
// data post-manipulation
'onRowParsed' => function (array $row) {
$row['other_stuff'] = do_some_stuff($row);
return $row;
},
'onChunkParsed' => function (array $rows) {
// do whatever you want, return void
},
'onError' => function (\Exception $e, $index) {
throw new \Exception($e->getMessage() . ": at line $index");
}
// CSV columns definition
'columns' => [
'A as id' => function (string $data) {
return (int) $data;
},
'B as firstname' => function (string $data) {
return ucfirst($data);
},
'C as name' => function (string $data) {
if (!$data) {
throw new \Exception("Name is mandatory and is missing");
}
return ucfirst($data);
},
// use of Optimizers (see at the end of this doc for more info)
'D as optimized' => new \voilab\csv\Optimizer(
function (string $data) {
return (int) $data;
},
function (array $data) {
return some_reduce_function($data);
}
)
]
]);
$str = <<<CSV
A; B
4; hello
2; world
CSV;
$parser = new \voilab\csv\Parser();
$result = $parser->fromString($str, [
'delimiter' => ';',
'columns' => [
'B' => function (string $data) {
// first call
return ucfirst($data);
},
'A' => function (string $data) {
// second call
return (int) $data;
}
]
]);
print_r($result);
/* prints:
Array (
[0] => Array (
[B] => Hello
[A] => 4
)
[1] => Array (
[B] => World
[A] => 9
)
)
*/
$str = <<<CSV
A; B
4; hello
2; world
...
CSV;
$parser = new \voilab\csv\Parser();
$resource = new \voilab\csv\CsvString($str);
$result = $parser->parse($resource, [
'delimiter' => ';',
'size' => 2,
'columns' => [
'B' => function (string $data) {
return ucfirst($data);
},
'A' => function (string $data) {
return (int) $data;
}
]
]);
$lastPos = $resource->tell();
$resource->close();
$resource2 = new \voilab\csv\CsvString($str);
$nextResult = $parser->parse($resource2, [
'delimiter' => ';',
'size' => 2,
'start' => 2, // yon **can** specify the start index. Not mandatory.
'seek' => $lastPos,
'columns' => [
'B' => function (string $data) {
return ucfirst($data);
},
'A' => function (string $data) {
return (int) $data;
}
]
]);
$errors = [];
$data = $parser->fromFile('file.csv', [
'onError' => function (\Exception $e, $index, array $meta, array $options) use (&$errors) {
$errors[] = "Line [$index]: " . $e->getMessage();
// do nothing more, so next columns and next lines can be parsed too.
// meta types are the following:
switch ($meta['type']) {
case 'init':
case 'column':
case 'row':
case 'reducer':
case 'optimizer':
case 'chunk':
}
},
'columns' => [
'email' => function (string $data) {
// accept null email but validate it if there's one
if ($data && !filter_var($data, FILTER_VALIDATE_EMAIL)) {
throw new \Exception("The email [$data] is invalid");
}
return $data ?: null;
}
]
]);
if (count($errors)) {
// now print in some ways all the errors found
print_r($errors);
} else {
// everything went well, put data in db on whatever
}
$data = $parser->fromFile('file.csv', [
'onError' => function (\Exception $e, $index, array $meta) {
if ($meta['type'] === 'init') {
// called during initialization.
var_dump($meta['key']); // for errors with specific key
if ($e->getCode() === \voilab\csv\Exception::HEADERMISSING) {
throw new \Exception(sprintf("La colonne [%s] est obligatoire", $meta['key']));
}
}
throw $e;
}
]);
$str = <<<CSV
A; B
4; updated John
2; updated Sybille
CSV;
$database = some_database_abstraction();
$data = $parser->fromString($str, [
'delimiter' => ';',
'columns' => [
'A as user' => new \voilab\csv\Optimizer(
// column function, same as when there's no optimizer
function (string $data) {
return (int) $data;
},
// reduce function that uses the set of datas from the 1st function
function (array $data) use ($database) {
$query = 'SELECT id, firstname FROM user WHERE id IN(?)';
$users = $database->query($query, array_unique($data));
return array_reduce($users, function ($acc, $user) {
$acc[$user->id] = $user;
return $acc;
}, []);
},
// absent function. data is [int] because the first function returns
// an [int]
function (int $data, int $index) {
throw new \Exception("User with id $data at index $index doesn't exist!");
}
),
'B as firstname' => function (string $data) {
return $data;
}
]
]);
print_r($result);
/* prints:
Array (
[0] => Array (
[user] => User ( id => 4, firstname => John )
[firstname] => updated John
)
[1] => Array (
[user] => User ( id => 2, firstname => Sybille )
[firstname] => updated Sybille
)
)
*/
$str = ''; // a hudge CSV string with tons of rows and two columns
$parser->fromString($str, [
'delimiter' => ';',
'chunkSize' => 500,
'onChunkParsed' => function (array $rows, int $chunkIndex, array $columns, array $options) {
// count($rows) = 500
// do something with your parsed rows. This method will be called
// as long as there are rows to parse.
// This method returns void
},
'onError' => function (\Exception $e, $index, array $meta) {
// if ($meta['type] === 'chunk') { do something }
},
'columns' => [
'A as name' => function (string $data) {
return (int) $data;
},
'B as firstname' => function (string $data) {
return $data;
}
]
]);
$str = 'A;B\r\n4;Hello\r\n;2;World';
$parser->fromString($str, [
'guessLineEnding' => new \voilab\csv\GuesserLineEnding([
// maximum line length to read, which will be parsed
// defaults to: see below
'length' => 1024 * 1024
])
]);
$str = 'A;B\n4;Hello\n;2;World';
$parser->fromString($str, [
'guessDelimiter' => new \voilab\csv\GuesserDelimiter([
// delimiters to check. Defaults to: see below
'delimiters' => [',', ';', ':', "\t", '|', ' '],
// number of lines to check. Defaults to: see below
'size' => 10,
// throws an exception if result is amiguous. Defaults to: see below
'throwAmbiguous' => true,
// score to reach for a delimiter. Defaults to: see below
'scoreLimit' => 50
])
]);
$str = 'A;B\n4;Hellö\n;2;Wörld';
$parser->fromString($str, [
'guessEncoding' => new \voilab\csv\GuesserEncoding([
// encoding in which data to retrieve. Defaults to: see below
'encodingTo' => 'utf-8',
// encoding in file. If null, is auto-detected
'from' => null,
// available encodings. If null, uses mb_list_encodings
'encodings' => null,
// strict mode for mb_detect_encoding. Defaults to: see below
'strict' => false
])
]);
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.