Detect and Repair Double-Encoded UTF-8 Text

Text such as “Français” often means UTF-8 bytes were decoded as Windows-1252 and the resulting characters were encoded as UTF-8 again. Repair is possible only when that byte history is known; do not repeatedly convert every string that merely looks unusual.

Last updated: September 26, 2026.

function undoWindows1252Mojibake(string $broken): string
{
    $candidate = mb_convert_encoding($broken, 'Windows-1252', 'UTF-8');

    if (!mb_check_encoding($candidate, 'UTF-8')) {
        throw new UnexpectedValueException('Pattern is not reversible as UTF-8');
    }

    return $candidate;
}

echo undoWindows1252Mojibake('Français'); // Français

The conversion recreates the original byte sequence by encoding the mojibake characters as Windows-1252. PHP strings are byte sequences, so the returned bytes can then be interpreted as UTF-8.

Prove the pattern on samples

Compare the broken and expected text, inspect hexadecimal bytes, and test several characters: accented letters, curly quotes, dashes, and currency signs. Some sequences are ambiguous or have already lost bytes. Keep a table of record IDs, original bytes, proposed result, and validation status.

Repair narrowly and reversibly

  1. Back up the original column and database.
  2. Select only rows matching the proven corruption pattern.
  3. Write repaired values to a staging column or table.
  4. Review counts and representative text.
  5. Swap values only after application and native-language checks pass.

Do not run the function twice. Add a migration marker or selection condition so a retry is idempotent. Correct text that contains “Ô legitimately must not be modified.

Fix the original boundary

Repairing data without fixing the importer, database connection, or HTTP declaration guarantees another incident. Trace the path using the broader mojibake guide. If the source is actually a legacy file, perform one deliberate Windows-1252-to-UTF-8 conversion. If the issue began during a database move, follow the MySQL migration checklist.

Related Web Cheat Sheet guides

Sergey Kornilov

Sergey Kornilov