Reputation: 12867
Consider this code:
$escapeChar = '"';
$source = fopen('E:/1.csv', 'r');
$row = fgetcsv($source, null, ',', '"', $escapeChar);
fclose($source);
$writeTo = fopen('E:/2.csv', 'w');
fputcsv($writeTo, $row, ',', '"', $escapeChar);
fclose($writeTo);
$read = fopen('E:/2.csv', 'r');
$row = fgetcsv($read, null, ',', '"', $escapeChar);
print_r($row);
With 1.csv like this:
"Affordable Dentist.""","Mon - Thu: 8:00 am - 5:00 pm Fri: 8:00 am - 1:00 pm Sat - Sun Closed\",,,"amex, cash, check, diners club, discover"
Run the code and it output:
Array
(
[0] => Affordable Dentist.",Mon - Thu: 8:00 am - 5:00 pm Fri: 8:00 am - 1:00 pm Sat - Sun Closed\"
[1] =>
[2] =>
[3] => amex, cash, check, diners club, discover
)
Then change $escapeChar:
$escapeChar = '\\';
And run the code again which output:
Array
(
[0] => Affordable Dentist."
[1] => Mon - Thu: 8:00 am - 5:00 pm Fri: 8:00 am - 1:00 pm Sat - Sun Closed\",,,amex
[2] => cash
[3] => check
[4] => diners club
[5] => discover"
)
It just seems whichever I use for the $escapeChar
, '\\'
or '"'
, it's wrong.
The correct final result should be like this:
Array
(
[0] => Affordable Dentist."
[1] => Mon - Thu: 8:00 am - 5:00 pm Fri: 8:00 am - 1:00 pm Sat - Sun Closed\
[2] =>
[3] =>
[4] => amex, cash, check, diners club, discover
)
How to make it right here so whatever CSV file read (1.csv) can be output correctly (2.csv) and then the output (2.csv) can again be parsed correctly?
Upvotes: 2
Views: 2558
Reputation: 173522
This proprietary escaping mechanism has been around for a long time, but since 7.4 you can switch this off:
The escape_char parameter now also accepts an empty string to disable the proprietary escape mechanism.
This would be your new code:
fputcsv($writeTo, $row, ',', '"', '');
// ^^ empty escape character
It will give the following output:
"Affordable Dentist.""","Mon - Thu: 8:00 am - 5:00 pm Fri: 8:00 am - 1:00 pm Sat - Sun Closed\",,,"amex, cash, check, diners club, discover"
Upvotes: 2
Reputation: 2384
To elaborate a bit more on the answer from @murat-tutumlu the problem is because you're using the double quote character as both the escape character and the enclosure character parameters to fgetcsv()
and fputcsv()
. The steps when reading the first item are:
"Affordable Dentist."""
Affordable Dentist.""
Affordable Dentist."
When you switch to using the backslash character as the escape character for all operations then the second item escapes the ending enclosure character and breaks the parsing in a different way.
I would recommend using a different escape character in your source data if possible. If you can't change the data then you can change your code to use double quote as the escape character for the first call to fgetcsv()
and then switch to an unused character for the subsequent calls.
$escapeChar = '"';
$source = fopen('E:/1.csv', 'r');
$row = fgetcsv($source, null, ',', '"', $escapeChar);
fclose($source);
// Need to use a different escape character from here
$escapeChar = '^';
$writeTo = fopen('E:/2.csv', 'w');
fputcsv($writeTo, $row, ',', '"', $escapeChar);
fclose($writeTo);
$read = fopen('E:/2.csv', 'r');
$row = fgetcsv($read, null, ',', '"', $escapeChar);
print_r($row);
Upvotes: 2
Reputation: 780
You need to use escape character for both fgetcsv() and fputcsv():
$objRow = array (
'general_info' => 'Affordable Dentist."',
'regular_hours' => 'Mon - Thu: 8:00 am - 5:00 pm Fri: 8:00 am - 1:00 pm Sat - Sun Closed',
'extra_phones' => '',
'services_products' => '',
'payment' => 'amex, cash, check, diners club, discover',
);
$csvHandle = fopen('test.csv', 'w');
fputcsv($csvHandle, $objRow, ',', '"', '\\');
fclose($csvHandle);
$csvHandle = fopen('test.csv', 'r');
$row = fgetcsv($csvHandle, null, ',', '"', '\\');
print_r($row);
Upvotes: 0