Re: [RFC] CSV Extension (ext/csv)
| From: | Artem Ukrainskiy | Date: | Sat, 10 Oct 2026 10:37:51 +0000 |
| Subject: | Re: [RFC] CSV Extension (ext/csv) | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-132860@lists.php.net to get a copy of this message | ||
This RFC led me to take a closer look at the built-in CSV functions, and
what I found makes me favor a different path to the same goals.
The RFC argues that their behavior "cannot be fixed without breaking
compatibility". I went through the list:
- $escape: already addressed by the PHP 8.4 deprecation; the default
changes to "" in PHP 9.0.
- Locale dependence: php/php-src#24207 (
https://github.com/php/php-src/pull/24207,
under review, prompted by this
RFC) removes the per-byte libc lookup for ASCII characters in
ASCII-compatible locales. The remaining isspace() before an opening
enclosure can be replaced with an explicit space/tab check. For non-ASCII
bytes in CJK locales, mbrlen() serves a purpose: a Shift_JIS character can
contain a '|' trail byte without that byte being a delimiter. A
locale-independent byte parser would split it.
- Single-byte delimiters and enclosures: longer values currently throw
ValueError, so support for multibyte tokens can be added without changing
existing valid calls.
- No inverse of str_getcsv(): a str_putcsv() function would fill that gap
and let SplFileObject::fputcsv() callers use
$file->fwrite(str_putcsv($row)).
- [null] for an empty line and whitespace before an enclosure: these can be
addressed by an opt-in strict mode without changing the default behavior.
Enclosing fields containing spaces on output is permitted by RFC 4180
section 2.5 and is not a compliance defect.
Strict validation, multibyte tokens, string serialization and lazy reading
can all be built on the existing API. Lazy iteration over a stream already
works with a generator around fgetcsv(); strict row-width validation can be
layered on top. These changes can be developed and reviewed independently,
without replacing the parser or breaking existing calls.
I have benchmarks and test scripts for the existing implementation and the
proposed extension here:
https://github.com/ArtUkrainskiy/php-src-bench/tree/main/reports/csv-pr-24199
Adding ext/csv instead would leave core maintaining two independent CSV
parsers for the foreseeable future. The RFC explicitly leaves the built-ins
unchanged, and the June discussion around the SplFileObject deprecations
showed understandable reluctance to remove existing APIs without an
established migration path (https://news-web.php.net/php.internals/131503,
and the August follow-up: https://news-web.php.net/php.internals/132186).
The branch itself is in good shape. The issues I reported on the PR were
addressed quickly, and the parser is now faster than fgetcsv() in my
benchmarks. This is not an objection to the implementation or the work that
went into it.
My concern is the long-term maintenance cost of introducing a second parser
when the existing one can be improved incrementally. I'd rather help land
those improvements in ext/standard.
пт, 9 окт. 2026 г. в 17:07, Damian Jóźwiak <damian.jozwiak.lodz@gmail.com>:
>
> Hi internals,
>
> I'd like to open the discussion on an RFC proposing a dedicated CSV
> extension (ext/csv) for PHP core.
>
> RFC: https://wiki.php.net/rfc/csv_extension
>
> Implementation: https://github.com/php/php-src/pull/24199
>
> The proposal builds upon Gina Peter Banyard's girgias/csv extension
> (BSD-3-Clause), with additional functionality for file and stream handling.
>
> The motivation includes the deprecation of the SplFileObject CSV methods
> in PHP 8.6, which leaves certain use cases without a direct replacement.
>
> The proposed extension provides:
>
> -
>
> Six functions and one class in the Csv\ namespace.
> -
>
> RFC 4180-compatible parsing and serialization by default.
> -
>
> Locale-independent processing without the proprietary escape mechanism..
> -
>
> Multibyte delimiters, enclosures, and EOL sequences.
> -
>
> Strict and lax collection parsing.
> -
>
> Lazy iteration over CSV files and streaming output.
>
> The implementation includes PHPT tests covering parsing, serialization,
> stream handling, resource lifetime, and various edge cases.
>
> The pull request's CI checks are currently passing across the tested
> platforms, including debug, ZTS, and AddressSanitizer configurations.
>
> The initial API is deliberately kept small. A more comprehensive
> object-oriented Reader/Writer API, including capability-oriented
> interfaces, is left for potential future discussion.
>
> I'd particularly appreciate feedback on the public API design, the naming
> of LazyLaxCollection, and whether the extension should be always enabled
> or optional at build time.
>
> For transparency, Gina has not reviewed or endorsed this RFC. Parts of the
> implementation were developed with LLM assistance; I have reviewed the code
> and take full responsibility for the contribution.
>
> This is an invitation for discussion, not a call for votes.
>
> Thanks in advance for your feedback.
>
> Best regards,
> Damian Jóźwiak
>
--
Best regards,
Artem Ukrainskiy