{"record":{"id":"55c4929f9987153a","repo":"PHPOffice/PHPWord","slug":"unable-to-convert-text-to-utf-8","errorCode":null,"errorMessage":"Unable to convert text to UTF-8","messagePattern":"Unable to convert text to UTF-8","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/PhpWord/Shared/Text.php","lineNumber":157,"sourceCode":"    public static function isUTF8($value = '')\n    {\n        return is_string($value) && ($value === '' || preg_match('/^./su', $value) == 1);\n    }\n\n    /**\n     * Return UTF8 encoded value.\n     *\n     * @param null|string $value\n     *\n     * @return ?string\n     */\n    public static function toUTF8($value = '')\n    {\n        if (null !== $value && !self::isUTF8($value)) {\n            // PHP8.2 : utf8_encode is deprecated, but mb_convert_encoding always usable\n            $value = (function_exists('mb_convert_encoding')) ? mb_convert_encoding($value, 'UTF-8', 'ISO-8859-1') : utf8_encode($value);\n            if ($value === false) {\n                throw new Exception('Unable to convert text to UTF-8');\n            }\n        }\n\n        return $value;\n    }\n\n    /**\n     * Returns unicode from UTF8 text.\n     *\n     * The function is splitted to reduce cyclomatic complexity\n     *\n     * @param string $text UTF8 text\n     *\n     * @return string Unicode text\n     *\n     * @since 0.11.0\n     */\n    public static function toUnicode($text)","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/PHPOffice/PHPWord/blob/aef95c04151b5633cc505f672ddd6a71da900ee1/src/PhpWord/Shared/Text.php#L139-L175","documentation":"Shared\\Text::toUTF8() converts non-UTF-8 (assumed ISO-8859-1) text using mb_convert_encoding or, on older setups, utf8_encode. It throws Exception if the conversion returns false, meaning the text could not be converted to UTF-8. It is used internally via ensureUtf8Encoded before text is written into documents.","triggerScenarios":"ensureUtf8Encoded()/toUTF8() called with a non-null string that is not valid UTF-8 and mb_convert_encoding($value,'UTF-8','ISO-8859-1') returns false (e.g. invalid input bytes, or mbstring absent and utf8_encode unavailable/blocked in PHP 8.2+).","commonSituations":"Text read from legacy databases or CSVs in Latin-1/Windows-1252 with byte sequences mbstring rejects; PHP 8.2+ where utf8_encode is deprecated and mbstring is not installed; passing null-adjacent or binary data as text.","solutions":["Ensure the mbstring extension is installed so mb_convert_encoding is always available.","Pre-sanitize input with mb_check_encoding($value,'UTF-8') and fix the source encoding explicitly (iconv with //IGNORE).","Set correct connection/character-set encoding (e.g. mysql charset utf8mb4) so text arrives as UTF-8 already.","Replace truly invalid bytes before conversion, e.g. iconv('Windows-1252','UTF-8//IGNORE',$value)."],"exampleFix":"// before\n$textrun->addText($row['name']); // Latin-1 from legacy DB\n// after\n$name = mb_check_encoding($row['name'], 'UTF-8')\n    ? $row['name']\n    : iconv('Windows-1252', 'UTF-8//IGNORE', $row['name']);\n$textrun->addText($name);","handlingStrategy":"try-catch","validationCode":"if (is_string($value) && !mb_check_encoding($value, 'UTF-8')) {\n    $value = iconv('Windows-1252', 'UTF-8//IGNORE', $value);\n}","typeGuard":null,"tryCatchPattern":"try {\n    $textrun->addText($value);\n} catch (\\PhpOffice\\PhpWord\\Exception\\Exception $e) {\n    if (str_contains($e->getMessage(), 'UTF-8')) {\n        $textrun->addText(mb_convert_encoding($value, 'UTF-8', 'ISO-8859-1//IGNORE'));\n    } else {\n        throw $e;\n    }\n}","preventionTips":["Install ext-mbstring everywhere (it is effectively required on PHP 8.2+)","Set correct DB connection charset (utf8mb4) so text arrives as UTF-8","Sanitize third-party/legacy text with mb_check_encoding before adding to documents"],"tags":["phpword","encoding","utf8","mbstring"],"backgroundTag":"text-encoding-conversion-failed","analyzedSha":"aef95c04151b5633cc505f672ddd6a71da900ee1","analyzedAt":"2026-09-14T10:53:58.933Z","contentChangedAt":"2026-09-14T10:53:58.933Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}