Strings7 min readExamples run on PHP 8.5.10

str_getcsv()

Learn how PHP 8.4 str_getcsv() splits a CSV string into fields, why you should pass escape explicitly, and which edge cases and mistakes to watch for.

Signature

str_getcsv(
    string $string,
    string $separator = ",",
    string $enclosure = "\"",
    string $escape = "\\"
): array
Available since PHP 5.3.07.48.08.18.28.38.48.5All versions →

Purpose

str_getcsv() reads a string written in CSV format and returns the fields it finds as an indexed array. It works on a string already in memory, so it suits a line from a log, a cell exported from a spreadsheet, or a value stored in a text column. For a file on disk, fgetcsv() is the usual companion.

Signature in PHP 8.4

Parameters and defaults

  • $string: the text to parse.
  • $separator: the character that divides fields. The default is a comma. It must be exactly one byte.
  • $enclosure: the character that wraps a field so it may contain separators. The default is a double quote. It must be exactly one byte.
  • $escape: the proprietary escape character. It must be one byte or the empty string. The default is a backslash, but as of PHP 8.4 relying on that default is deprecated. Pass the value explicitly, either positionally or as a named argument such as escape: ''.

An empty $escape turns off PHP's own escape mechanism. That is the recommended choice, because a non-empty escape character can produce results that do not follow RFC 4180 and may not survive a round trip through PHP's CSV functions. Inside a quoted field, a doubled enclosure character always yields one literal enclosure character, whatever $escape is.

Return value and failures

The function returns an indexed array of fields. Every field is a string, so 42 arrives as "42" and you must convert it yourself. Parsing a completely empty string gives [null], an array with one null element, not an empty array.

In PHP 8.4, a ValueError is thrown if $separator or $enclosure is not one byte long, or if $escape is neither one byte nor the empty string.

Example 1: a simple line

With plain values and no quotes, each comma starts a new field.

Example
<?php
$row = str_getcsv('PHP,Java,Python', escape: '');
echo json_encode($row, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
["PHP","Java","Python"]

Example 2: quoted fields

A field wrapped in the enclosure may contain the separator. Inside it, two quote characters in a row stand for one literal quote.

Example
<?php
$line = '"Smith, Ana",42,"She said ""hi"""';
$fields = str_getcsv($line, ',', '"', '');
echo json_encode($fields, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
["Smith, Ana","42","She said \"hi\""]

The comma in the first field does not split it, and the number stays a string.

Example 3: empty input and empty fields

A custom separator is passed as the second argument. Adjacent separators produce empty strings, and a trailing separator produces an empty last field.

Example
<?php
$empty = str_getcsv('', escape: '');
$gaps = str_getcsv('a;;c;', ';', '"', '');
echo json_encode($empty), "\n";
echo json_encode($gaps), "\n";
Output
[null]
["a","","c",""]

Edge cases

  • Empty string: the result is [null]. Check for an empty input before parsing if you need to tell "no data" from "one missing value".
  • Empty fields: consecutive separators give "" entries, so the field count stays predictable.
  • Invalid control characters: a multi-character separator such as '::' throws a ValueError. Catch it if the separator comes from user configuration.
  • Locale: the function takes locale settings into account. Data in some one-byte encodings may be parsed incorrectly when LC_CTYPE is a UTF-8 locale.
  • Unterminated enclosure: since PHP 8.3, if the last field contains only an unterminated enclosure, the result is an empty string rather than a string holding a single null byte.

Common mistakes

  1. Relying on the default escape. In 8.4 this is deprecated. Write escape: '' or pass all four arguments.
  2. Splitting with explode(',', ...). That ignores quotes and breaks on "Smith, Ana". Use str_getcsv() for anything that might be quoted.
  3. Treating it as a whole-document parser. The function is meant for one record. A quoted field may contain a line break, so cutting a multi-line document apart with explode("\n", ...) can split a record in the wrong place. For files, read with fgetcsv() or SplFileObject.
  4. Expecting typed values. Numbers, booleans and dates all come back as strings.
  5. Forgetting the [null] case. Looping over the result of an empty string still runs once.
  6. Using a multi-byte separator or enclosure. Both must be a single byte, so a character like "§" is rejected.
  • fgetcsv() reads and parses a line from an open file pointer.
  • fputcsv() formats an array as a CSV line and writes it to a file pointer.
  • SplFileObject::fgetcsv() and SplFileObject::setCsvControl() offer the same behavior in an object-oriented form.
  • explode() is fine only when the data never contains quoting.

Recap

str_getcsv() turns one CSV record into an array of string fields. Pass escape explicitly (an empty string is the safest choice in PHP 8.4), remember that empty input yields [null], convert numeric strings yourself, and keep each call to one record.

Tested examples

Parse a simple comma-separated line
<?php
$row = str_getcsv('PHP,Java,Python', escape: '');
echo json_encode($row, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
["PHP","Java","Python"]
Quoted fields with a comma and doubled quotes
<?php
$line = '"Smith, Ana",42,"She said ""hi"""';
$fields = str_getcsv($line, ',', '"', '');
echo json_encode($fields, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
["Smith, Ana","42","She said \"hi\""]
Empty input, empty fields and a custom separator
<?php
$empty = str_getcsv('', escape: '');
$gaps = str_getcsv('a;;c;', ';', '"', '');
echo json_encode($empty), "\n";
echo json_encode($gaps), "\n";
Output
[null]
["a","","c",""]