Skip to content

fputcsv incorrectly escapes when quote char is both enclosure and escape char #18348

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
vavra opened this issue Apr 17, 2025 · 4 comments
Open

Comments

@vavra
Copy link

vavra commented Apr 17, 2025

Description

The following code:

<?php
fputcsv($fh, ['Jan', 'He said "Hello"', "Line1\nLine2"], ';', '"', '"');

Resulted in this output:

Jan;"He said "Hello"";"Line1
Line2"

But I expected this output instead:

"Jan";"He said ""Hello""";"Line1

In the expected output it should be the quote chars doubled and whole second cell should be by quote chars enclosed. Expected output will be then properly read by Excel (we use Czech, so semicolon used as col separator)

PHP Version

PHP Version 8.4.6
Windows NT ___ 10.0 build 22631 (Windows 11) AMD64

Operating System

Windows

@DanielEScherzer
Copy link
Member

https://3v4l.org/pshQW reproducible

@SakiTakamachi
Copy link
Member

Apparently, when both enclosure and escape characters are present, this can lead to unintended behavior.

<?php
$row = ['J"a"n', 'He said "Hello"', 'Line1\\Line2'];

$fh = fopen("php://temp", "r+");
fputcsv($fh, $row, ',', '"', 'a');
rewind($fh);
echo stream_get_contents($fh);
"J""a"n","He said ""Hello""",Line1\Line2

https://3v4l.org/QgEMq

I'll think about how to fix it

@SakiTakamachi
Copy link
Member

Ah, no.

Warning
When escape is set to anything other than an empty string ("") it can result in CSV that is not compliant with » RFC 4180 or unable to survive a roundtrip through the PHP CSV functions. The default for escape is "\" so it is recommended to set it to the empty string explicitly. The default value will change in a future version of PHP, no earlier than PHP 9.0.

https://www.php.net/manual/en/function.fgetcsv.php

This appears to be the intended behavior.

@Girgias
Copy link
Member

Girgias commented Apr 22, 2025

As usual with anything CSV related I plug in my ext/csv extension which solves these issues as it is conformant to RFC 4180: https://packagist.org/packages/girgias/csv

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants