Last updated: August 29, 2026.
CSV has no universal in-band encoding declaration. Spreadsheet software often guesses, so identify the exporting system’s encoding before converting.
Preserve the original
Detection functions provide hints rather than certainty because short byte sequences can be valid in several encodings. Keep the source and test records containing accents, quotes, and currency symbols.
Parse rows while converting
Use fgetcsv behavior through SplFileObject so quoted commas and embedded line breaks remain valid.
<?php
$input = new SplFileObject(__DIR__ . '/legacy.csv', 'rb');
$output = new SplFileObject(__DIR__ . '/utf8.csv', 'wb');
$input->setFlags(SplFileObject::READ_CSV);
foreach ($input as $row) {
if ($row === [null]) continue;
$row = array_map(
static fn ($v) => mb_convert_encoding((string) $v, 'UTF-8', 'Windows-1252'),
$row
);
$output->fputcsv($row);
}Encoding is not the delimiter
A semicolon-delimited file can still be UTF-8, and a comma-delimited file can still be Windows-1252. Confirm both settings. Validate row counts and the first header after conversion; a BOM can become part of that first field.
Treat encoding and CSV structure separately
Convert decoded field values, not arbitrary chunks of the file, so quoted commas, embedded line breaks, and escaped quotes remain valid. Identify the source encoding from the exporting system whenever possible instead of trusting automatic detection.
Compare input and output row counts, inspect the header, and test fields containing punctuation and non-ASCII names. Then open the result in the actual receiving application because spreadsheet import defaults vary.
- Preserve the original export.
- Set the delimiter explicitly.
- Check whether a BOM is required by the receiver.
Keep the byte encoding, declaration, storage, and decoder consistent. When diagnosing a problem, preserve the original input and change one boundary at a time so the actual cause remains visible.
Continue with UTF-8 BOM guidance, large CSV processing, and encoding comparison.
Reference: PHP fgetcsv reference.