str_getcsv
Parses one line of CSV text into an array of fields.
str_getcsv(string $string, string $separator = ",", string $enclosure = "\"", string $escape = "\\"): array- Added in PHP 5.3.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$string | string | The CSV line to parse. |
$separatoroptional | string= "," | The field delimiter. Must be exactly one byte. |
$enclosureoptional | string= "\"" | The field enclosure character. Must be exactly one byte. |
$escapeoptional | string= "\\" | The escape character. Must be exactly one byte, or the empty string to disable the proprietary escape mechanism. |
Return value
arrayAn indexed array of the fields read from the line.
Errors
Throws a ValueError if separator or enclosure is not exactly one byte, or if escape is neither one byte nor the empty string.
Changelog
- PHP 8.4Relying on the default value of escape is deprecated; pass it explicitly (escape: '' is the RFC 4180-compliant choice).
- PHP 8.4Throws a ValueError if separator, enclosure or escape is invalid, matching fgetcsv() and fputcsv().
- PHP 8.3A final field consisting only of an unterminated enclosure now yields an empty string instead of a single null byte.
- PHP 7.4An empty escape now disables the proprietary escape mechanism; previously it was treated as the default value.
str_getcsv parses a single line of CSV that you already have in memory. Unlike explode(',', $line) it understands quoting, so a comma inside "Smith, Jane" stays part of the field.
When to reach for it
Use it when the CSV arrives as a string rather than a file: a pasted textarea, an API payload, a database column, one line pulled from a queue. For an actual file, fgetcsv is better — it handles embedded newlines inside quoted fields, which str_getcsv cannot see because it only ever gets one line.
What trips people up
Two things. First, PHP's escape parameter is not part of RFC 4180. By default a backslash is treated as an escape character, so "c\"d" parses in a way real spreadsheets never intended. Since PHP 8.4 relying on that default is deprecated and emits a notice — pass escape: '' explicitly, which both silences the deprecation and gives standards-compliant parsing. The default is expected to change in PHP 9.
Second, an empty line returns [null], not []. Test with $row === [null] before treating a row as data, or a trailing newline in your input will produce a phantom record.
Example
When to use it
- Parse a CSV line pasted into a textarea or stored in a database column
- Split a delimited API response line that may contain quoted commas
- Convert a header line plus a data line into an associative row with array_combine
- Handle a pipe- or tab-delimited line by passing a custom separator
Frequently asked questions
What is the difference between str_getcsv and fgetcsv?
fgetcsv reads and parses one record from an open file handle and can span multiple physical lines when a field contains a newline; str_getcsv parses a string you already hold and sees only what you pass it. Use fgetcsv for files, str_getcsv for in-memory text.
Why does PHP 8.4 warn about the escape parameter?
The default backslash escape is a PHP-specific extension that is not RFC 4180 compliant, so relying on the default is deprecated. Pass escape: '' explicitly to disable it and get standard CSV parsing.
Why does str_getcsv return an array containing null?
That is what an empty input line produces: [null] rather than an empty array. Check for it explicitly, usually with $row === [null], before treating the result as a record.
More examples
Header row plus data rows
The first line becomes the key list and every following line is zipped against it with array_combine, producing associative rows. The quoted "Porto, PT" stays a single field, which is exactly what explode(',') would have got wrong. The array_filter is what removes the empty final line so it never reaches str_getcsv.
<?php
$csv = "id,name,city\n1,Ana,\"Porto, PT\"\n2,Bruno,Lisbon\n";
$lines = array_filter(explode("\n", $csv), fn ($l) => $l !== '');
$header = str_getcsv(array_shift($lines), ',', '"', '');
foreach ($lines as $line) {
print_r(array_combine($header, str_getcsv($line, ',', '"', '')));
}Custom separator and enclosure
The first call treats the pipe as the delimiter and a single quote as the enclosure, so "beta|gamma" survives as one field. The second parses tab-separated values with the same function. The last call passes a two-byte separator, which throws a ValueError since PHP 8.4 rather than silently using the first byte.
<?php
$pipe = "alpha|'beta|gamma'|delta";
print_r(str_getcsv($pipe, '|', "'", ''));
$tsv = "a\tb\tc";
print_r(str_getcsv($tsv, "\t", '"', ''));
try {
str_getcsv('a,b', ',,', '"', '');
} catch (ValueError $e) {
echo 'ValueError: ', $e->getMessage(), "\n";
}
Discussion