Um gültige UTF-8 in PHP
Ich bin mit PHP-verarbeiten von text aus einer Vielzahl von Quellen. Ich erwarte nicht, daß es etwas anderes als UTF-8, ISO 8859-1, oder vielleicht Windows-1252. Wenn es etwas anderes als einer von denen, ich muss nur sicherstellen, dass der text gedreht wird in eine gültige UTF-8-string, auch wenn die Zeichen gehen verloren. Hat die //TRANSLIT option von iconv gelöst?
Zum Beispiel würde dieser code sicherzustellen, dass eine Zeichenfolge ist sicher zum einfügen in eine UTF-8-kodierten Dokument (oder eine Datenbank)?
function make_safe_for_utf8_use($string) {
$encoding = mb_detect_encoding($string, "UTF-8,ISO-8859-1,WINDOWS-1252");
if ($encoding != 'UTF-8') {
return iconv($encoding, 'UTF-8//TRANSLIT', $string);
}
else {
return $string;
}
}
Du musst angemeldet sein, um einen Kommentar abzugeben.
UTF-8 speichern kann jedes Unicode-Zeichen. Wenn Ihre Codierung ist nichts anderes, einschließlich ISO-8859-1 oder Windows-1252, UTF-8 speichern kann jedes Zeichen in es. So dass Sie nicht haben, um sorgen über den Verlust jedes Zeichen, wenn Sie konvertieren eine Zeichenfolge aus irgendeiner anderen Kodierung auf UTF-8.
Weiter, beide, ISO-8859-1 und Windows-1252 single-byte-Codierungen, wo jedes byte gültig ist. Es ist technisch nicht möglich, zwischen Ihnen zu unterscheiden. Ich würde wählte Windows-1252 als Ihre Standard-match für nicht-UTF-8-Sequenzen, als nur die bytes entschlüsseln unterschiedlich sind im Bereich 0x80-0x9F. Diese Dekodieren verschiedene Zeichen wie typografische Anführungszeichen und der Euro ist in Windows-1252, in der Erwägung, dass in ISO-8859-1 Sie sind unsichtbare steuerzeichen, die werden fast nie benutzt. Web-Browser können manchmal sagen, Sie sind mit ISO-8859-1, aber oft sind Sie wirklich mit Windows-1252.
Würden Sie sicherlich möchten, legen Sie die optionalen 'strict' - parameter auf "TRUE" für diesen Zweck. Aber ich bin mir nicht sicher, ob dies tatsächlich deckt alle ungültigen UTF-8-Sequenzen. Die Funktion hat nicht den Anspruch, zu überprüfen, eine byte-Sequenz UTF-8 Geltung ausdrücklich zu. Es wurden Fälle bekannt, in denen mb_detect_encoding denke, UTF-8 falsch vor, aber ich weiß nicht, ob das kann immer noch passieren im strict-Modus.
Wenn Sie sicher sein wollen, tun Sie es selbst mithilfe der W3-empfohlenen regex:
?
/*
/+
Sequenzen, die verursachen können, es zu haben, um backtrack auf der Suche nach verschiedenen Möglichkeiten zu entsprechen. Das wird nicht passieren, in diesem Fall.chr(0)
). Es ist in Ordnung für druckbare Zeichen, aber nicht generisch UTF-8...^(a)+$
fehl 203-byte-input... das kann man doch nicht erwarten/akzeptables Verhalten? Es scheint gut zu funktionieren in R (die auch verwendet PCRE), für was es Wert ist. Ich denke, Rasmus ignoriert ist ein echtes problem. 🙁Mit der mbstring Bibliothek, Sie haben mb_check_encoding().
Anwendungsbeispiel:
Mit PHP 7.1.9 auf einem aktuellen Windows-10-system, das regex Lösung übertrifft
mb_check_encoding()
für eine beliebige Zeichenkette der Länge (immer noch 20.000 Iterationen):mb_check_encoding()
=> 64 msmb_check_encoding()
=> 2.4 sNur ein Hinweis: Anstatt der oft empfohlen (eher komplexen) regulären Ausdruck durch das W3C, können Sie einfach das " u " - Modifizierer zu testen, die eine Zeichenfolge für UTF-8-Gültigkeit:
Haben Sie einen Blick auf http://www.phpwact.org/php/i18n/charsets für eine Anleitung über Zeichensätze. Diese Seite enthält links zu einer Seite, die speziell für UTF-8.
Antwort auf "iconv ist idempotent":
Weder die iconv - iconv ist nicht idempotent.
Einen großen Unterschied zwischen
utf8_encode()
undiconv()
ist, dass iconv kann Fehler auslösen, wie dieses "Erkannt und einen incomplete multibyte character in input string", auch mit:in den obigen code:
Müssen Sie wissen
mb_detect_encoding
. Es kann die Antwort zu den uft-8 auch für ungültige UTF-8-strings (schlecht gebildet UTF-8).