Download the PHP package voilab/csv without Composer
On this page you can find all versions of the php package voilab/csv. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Informations about the package csv
CSV parser
This class uses fgetcsv
to parse a file or a string, extract columns and
provide per-column methods to manipulate data.
It can parse large files, HTTP streams, any types of resources, or strings.
It comes with a basic error handling, so it is possible to collect all errors in the CSV resource and, then, do something with this array of errors.
It is extendable, so you can parse your own type of resource/stream, if you have very special needs.
Table of content
- Install
- Install PHP5 compatible version
- Usage
- Available methods
- Simple example
- Full example
- Documentation
- Options
- Column function parameters
- Headers auto-sanitization
- On before column parse function parameters
- On row parsed function parameters
- Aliasing columns
- Required columns
- No header
- Shuffling columns when defining them
- Seek in big files
- Close the resource
- Line endings problems
- Error management
- Initialization errors
- Error and internationalization (i18n)
- Working with database, column optimization
- Parse function
- Reduce function
- Absent function
- Example
- Chunks
- Guessers : auto detect line ending, delimiter and encoding
- Guess line ending
- Guess delimiter
- Guess encoding
- Known issues
- Testing
- Security
- License
Install
Via Composer
Create a composer.json file in your project root:
Install PHP5 compatible version
This PHP5 version can't parse streams nor iterables.
Usage
Available methods
Simple example
Full example
Documentation
Options
These are the options you can provide at constructor level or when calling
from*
methods. Details for fgetcsv
options can be found here:
https://php.net/fgetcsv and https://php.net/str_getcsv
Name | Type | Default | Description |
---|---|---|---|
delimiter | string |
, |
fgetcsv the delimiter |
enclosure | string |
" |
fgetcsv the enclosure string. To tell PHP there isn't enclosure, set to and empty string |
escape | string |
\\ |
fgetcsv the escape string |
length | int |
0 |
fgetcsv the line length |
autoDetectLn | bool |
null |
If supplied, set the PHP ini param auto_detect_line_endings . Doesn't work with PSR streams. |
metadata | array |
[] |
Resource metadata. May be used internally by the resource |
close | bool |
false |
Tells if resource must be closed after parsing is done |
lineEnding | string |
\n |
Used with PSR streams to define what is a line ending. You must set a length, so it's possible to read a line |
headers | bool |
true |
Tells that CSV resource has the first line as headers |
strict | bool |
false |
Tells if columns defined in [columns] option must match exactly the number of columns in CSV resource |
required | array |
[] |
Columns defined in [columns] options that must be present in CSV resource (if aliased, must be the column alias) |
start | int |
0 |
Line index to start with. Used in big files, in conjunction with [size] option. The first index of data is 0 , regardless of headers |
size | int |
0 |
Number of lines to process. 0 ignores [start] and [size] |
seek | int |
0 |
Pointer position in file, used in conjunction with [size]. Take over [start] to define the starting position |
autotrim | bool |
true |
Trim all cell content, so you have always trimmed data in you columns functions |
chunkSize | int |
0 |
Number of rows to parse (including optimizer) to create a chunk |
onChunkParsed | callable |
null |
Method called when a chunk is complete |
onBeforeColumnParse | callable |
null |
Method called just before any defined column method |
guessDelimiter | GuesserDelimiterInterface |
null |
Object used to guess delimiter |
guessLineEnding | GuesserLineEndingInterface |
null |
Object used to guess line ending |
guessEncoding | GuesserEncodingInterface |
null |
Object used to guess content encoding. Call to this class is done before [onBeforeColumnParse] |
onRowParsed | callable |
null |
Method called when a row has finished parsing |
onError | callable |
null |
Method called when an error occurs, at column and at row level |
columns | array |
CSV columns definition (see examples). This option is the only one required |
Column function parameters
When defining a function for a column, you have access to these parameters:
Name | Type | Description |
---|---|---|
$data | string |
The first argument will always be a string. It is the cell content (trimmed if autotrim is set to true) |
$index | int |
The line index actually parsed. Correspond to the line number in the CSV resource (taken headers into account) |
$row | array |
The entire row data, raw from fgetcsv . These datas are not the result of the columns functions |
$parsed | array |
The parsed data from previous columns (columns are handled one after the other) |
$meta | array |
The current column information |
$options | array |
The options array |
------ | ------ | ------------- |
return | ?mixed |
Returns final cell value |
Headers auto-sanitization
Note that headers are automatically trimmed and their carriage returns are
removed. Also, all spaces following a space are removed. This is only for the
headers. Cells content are not manipulated, except if autotrim
is true.
If the column you defined in your code doesn't exist in CSV resource and doesn't appear in
required
array, the$meta
argument will have a flagphantom
set totrue
. This is the way to know if the column exists or not in the CSV resource during parsing.
On before column parse function parameters
Just before any CSV column data is parsed, a standard method is called so you can operate the same way on every rows and columns data. You can use that to manage encoding, for example.
Name | Type | Description |
---|---|---|
$data | string |
The first argument will always be a string. It is the cell content (trimmed if autotrim is set to true) |
$index | int |
The line index actually parsed. Correspond to the line number in the CSV resource (taken headers into account) |
$meta | array |
The current column information |
$options | array |
The options array |
------ | ------ | ------------- |
return | string |
Returns cell value |
Be aware of type declaration in your columns functions if you want to return other types from here.
On row parsed function parameters
When a row is completed, you can do something with all that data.
Name | Type | Description |
---|---|---|
$rowData | array |
All the data parsed, for all the columns |
$index | int |
The line index actually parsed. Correspond to the line number in the CSV resource (taken headers into account) |
$parsed | array |
The parsed data from previous rows (rows are handled one after the other) |
$options | array |
The options array |
------ | ------ | ------------- |
return | array |
Returns a multidimensional array of ?mixed values |
Aliasing columns
You can define aliases for columns to ease data manipulation. Just write as
to activate this functionality, like CSV column name as alias
.
Alias must not itself contain as
string. But in the CSV resource, the
header can have such a string.
Note that if you have
as
in a CSV resource header, you must alias it in the columns definitions. Otherwise, the parser will not find this column.
Required columns
If you have aliased a column, and it is a required column, you must use the
alias inside the required
option.
No header
If you have no header in you CSV resource, you need to define the parser like this.
Shuffling columns when defining them
You can define your columns in any order you want. You don't need to provide them in the order they appear in the CSV. You just have to match your keys with a header in the CSV resource.
Note that the execution order of the columns are aligned with your code. In the example below, the function
A()
is called afterB()
, even if column A appears first in CSV resource.
Seek in big files
You can use the seek mechanism to accelerate parsing big files.
Yon can specify the start index. But it is not mandatory. It is used in the error managment, to know which line bugs, or in the other methods calls, where [$index] is given.
You are responsible for keeping [seek] and [start] snychronized. If you don't, and you have errors, the indexes would be irrelevant.
Close the resource
Using fromString()
and fromFile()
methods, the resource will be closed
automatically. With other from*()
methods, you can close the resource by
giving the 'close' => true
option.
Line endings problems
Just as stated in official documentation, if you have problems with recognition in line endings, you can use the option below to activate auto detect.
$parser->parse($resource, [ 'autoDetectLn' => true ]);
Note that auto detect PHP ini param is not reseted to initial value after the parsing has finished.
When parsing streams (like HTTP response message body), line ending must be specified in the array options.
Error management
You can use the onError
option to collect all errors, so you can give a
message to the user with all errors in the file you found, in one shot.
You can stop the process of a row by checking the $meta
argument. It has a
key type
which can be row
or column
. If it's column
, you can throw the
error and it will call onError
again, but with type row
. Other columns will
be skipped for this row.
If you use an optimizer, you can call an Exception from there too. The key
type
will then have the value optimizer
.
Initialization errors
Some errors are thrown before any line is parsed. You have to take this into account.
Error and internationalization (i18n)
If you want to translate error messages, you can use the onError
function
with meta['type'] === 'init'
to throw the translated message.
Working with database, column optimization
When parsing large set of data, if one column is, for example, a user ID, it's
a bad idea to call a find($id)
method for each CSV row iteration. It's better
to take all column values, and call for a findByIds($ids)
.
The build-in class Optimizer
allows you to define a column this way. It takes
three arguments. The first is the function needed to parse value from CSV.
The second is a reduce function. It recieves all data of the column, and must
return an indexed array.
For example, if you have 2 rows with values a
and b
, the indexed result of
the reduce function would be Array ( a => something, b => something else )
.
The third argument is a function called when a value is not found in the reduced function.
Parse function
Same as Column function (see above)
Reduce function
Name | Type | Description |
---|---|---|
$data | array |
All the data parsed, for the column |
$parsed | array |
The parsed data (complete set of data) |
$optimized | array |
Columns already optimized. Key => value pair, where key is column name and value is the reduced function result of the column |
$meta | array |
The current column information |
$options | array |
The options array |
------ | ------ | ------------- |
return | array |
Returns an indexed array |
Returns an indexed array. If there's no correspondance between CSV column values and the result of the reduce function, you should not return the missing value. For example, if values are [10, 22], they are used in database query to find users by id, and user ID 22 doesn't exist, the result should be
Array ( 10 => User(id=10) )
Absent function
When a value is not found in the reduced result, the default behaviour is to set the value (like there wasn't any reduce function for this row). You can override this by defining the absent function, and do what you want with the value.
Name | Type | Description |
---|---|---|
$value | mixed |
The data parsed for the column, for this row |
$index | int |
The line index actually parsed. Correspond to the line number in the CSV resource (taken headers into account) |
$parsed | array |
The parsed data of this row |
$optimized | array |
Columns already optimized. Key => value pair, where key is column name and value is the reduced function result of the column |
$meta | array |
The current column information |
$options | array |
The options array |
------ | ------ | ------------- |
return | ?mixed |
Returns the default value for this "not found" key |
If you have defined an error function, it will be called with a type of
optimizer
(check error management above) if you throw an error from here.
Example
Chunks
Optimizers are good in certain cases, but sometimes you want to parse your data by chunk, maniuplate it, store it, and do it again with the next chunk. You can achieve this with chunks options:
If you use optimizers,
$rows
will be the resultset optimized.You don't need to use the array returned by
fromString
(or alike) because what you did inonChunkParsed
is enough.
Guessers : auto detect line ending, delimiter and encoding
Guessing how CSV data is structured (line ending, delimiter or encoding) is a very hasardous task, with so many use-cases it's impossible to rule them all..
This package still provides a way to guess these elements, but if it doesn't fit your needs, you can easily extend or create a new class and manage your specific use-case.
If you want to implement guessing your own way, please read the code base for each guessing interfaces.
Guessing is useless with some CsvInteface implementations. For example, iterables are ignored, since data is already arranged in cells and rows. Be sure it's useful for you before you use guessing features.
Guess line ending
First thing the parser does is to detect which are the line endings. The
provided implementation tries to detect line endings among \n
, \r
and \r\n
.
Guess delimiter
Then, the parser tries to detect delimiter. In the provided implementation, an exception is thrown if delimiter is not found or if it's too ambiguous.
Guess encoding
For each cell, encoding auto detection is called. The provided implementation tries to find the current cell encoding, and encode it to the other one given in the constructor.
It is also called for the header row. If you want to encode differently
between headers and datas, you can check on $meta['type'] === 'init'
in
your encode
function (check code base).
This guesser is called BEFORE onBeforeColumnParse
Known issues
- with PSR streams, carriage returns are not supported in headers and in cells content
- guessing processes are unlikely to fit your specific needs immediately. Before creating an issue or a PR, try to extends the guess classes and make your own specific adaptations
Testing
Security
If you discover any security related issues, please use the issue tracker.
License
The MIT License (MIT). Please see License File for more information.