Last updated: August 29, 2026.
Mojibake appears when bytes written in one encoding are decoded as another. The repair belongs at the first layer that interprets the bytes incorrectly, not in a chain of display-time conversions.
Trace the bytes
Inspect the original file, HTTP Content-Type header, HTML meta declaration, database column, and database connection. Keep an untouched copy before changing stored data.
- Check the response header in browser developer tools.
- Confirm the editor’s actual file encoding.
- Test accents, smart quotes, currency symbols, and emoji.
- Verify the database connection charset separately from the column charset.
Convert a known source
When the source is known to be Windows-1252, convert it once to UTF-8 and store the result.
<?php
$legacy = file_get_contents(__DIR__ . '/incoming.txt');
if ($legacy === false) {
throw new RuntimeException('Unable to read input.');
}
$utf8 = mb_convert_encoding($legacy, 'UTF-8', 'Windows-1252');
file_put_contents(__DIR__ . '/converted.txt', $utf8, LOCK_EX);Make output consistent
Serve UTF-8 in the HTTP header, declare it in HTML, and use a UTF-8 database connection. Changing only the meta element changes decoding instructions; it does not repair damaged stored bytes.
Trace the bytes from source to display
Mojibake is usually created at one boundary: import, database connection, template output, or HTTP decoding. Identify the first place the text becomes wrong rather than applying repeated conversions to already damaged data.
Compare a known value at every boundary and inspect the response Content-Type. Test outside the browser as well, because a browser can hide a server mistake by guessing the encoding.
- Back up data before conversion.
- Avoid decoding the same bytes twice.
- Use utf8mb4 for MySQL text that may contain emoji.
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 encoding comparison, MySQL collation conflicts, and CSV encoding repair.
Reference: MDN character encoding glossary.