str_getcsv

Parses one line of CSV text into an array of fields.

Signature
str_getcsv(string $string, string $separator = ",", string $enclosure = "\"", string $escape = "\\"): array
  • Added in PHP 5.3.0

Parameters

ParameterTypeDescription
$stringstringThe CSV line to parse.
$separatoroptionalstring= ","The field delimiter. Must be exactly one byte.
$enclosureoptionalstring= "\""The field enclosure character. Must be exactly one byte.
$escapeoptionalstring= "\\"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

Try it yourself
Loading editor…
Press Run to execute the code.

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.

Example · php
<?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.

Example · php
<?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

  • Be the first to comment on this lesson.