Ich lese viele Texte aus verschiedenen RSS-Feeds vor und füge sie in meine Datenbank ein.
Natürlich werden in den Feeds verschiedene Zeichencodierungen verwendet, z. B. UTF-8 und ISO 8859-1.
Leider gibt es manchmal Probleme mit der Kodierung der Texte. Beispiel:
Das "ß" in "Fußball" sollte in meiner Datenbank so aussehen: "Ÿ". Wenn es sich um ein "" handelt, wird es korrekt angezeigt.
Manchmal sieht das "ß" in "Fußball" in meiner Datenbank so aus: "ß". Dann wird es natürlich falsch angezeigt.
In anderen Fällen wird das "ß" als "ß" gespeichert - also ohne Änderung. Dann wird es auch falsch angezeigt.
Was kann ich tun, um die Fälle 2 und 3 zu vermeiden?
Wie kann ich alles gleich codieren, vorzugsweise UTF-8? Wann muss ich verwenden utf8_encode()
, wann muss ich verwenden utf8_decode()
(es ist klar, was der Effekt ist, aber wann muss ich die Funktionen verwenden?) Und wann darf ich nichts mit der Eingabe tun?
Wie mache ich alles gleich codiert? Vielleicht mit der Funktion mb_detect_encoding()
? Kann ich dafür eine Funktion schreiben? Meine Probleme sind also:
- Wie finde ich heraus, welche Codierung der Text verwendet?
- Wie konvertiere ich es in UTF-8 - unabhängig von der alten Codierung?
Würde eine solche Funktion funktionieren?
function correct_encoding($text) {
$current_encoding = mb_detect_encoding($text, 'auto');
$text = iconv($current_encoding, 'UTF-8', $text);
return $text;
}
Ich habe es getestet, aber es funktioniert nicht. Was stimmt damit nicht?
quelle
Antworten:
Wenn Sie
utf8_encode()
eine bereits UTF-8-Zeichenfolge anwenden , wird eine verstümmelte UTF-8-Ausgabe zurückgegeben.Ich habe eine Funktion erstellt, die all diese Probleme behebt. Es heißt
Encoding::toUTF8()
.Sie müssen nicht wissen, wie Ihre Zeichenfolgen codiert sind. Es kann Latin1 ( ISO 8859-1) , Windows-1252 oder UTF-8 sein, oder die Zeichenfolge kann eine Mischung aus diesen haben.
Encoding::toUTF8()
konvertiert alles in UTF-8.Ich habe es getan, weil ein Dienst mir einen Daten-Feed gab, der alle durcheinander brachte und UTF-8 und Latin1 in derselben Zeichenfolge mischte.
Verwendungszweck:
Herunterladen:
https://github.com/neitanod/forceutf8
Ich habe eine weitere Funktion
Encoding::fixUFT8()
hinzugefügt, die jede UTF-8-Zeichenfolge repariert, die verstümmelt aussieht.Verwendungszweck:
Beispiele:
wird ausgegeben:
Ich habe die Funktion (
forceUTF8
) in eine Familie statischer Funktionen für eine Klasse namens umgewandeltEncoding
. Die neue Funktion istEncoding::toUTF8()
.quelle
Sie müssen zuerst feststellen, welche Codierung verwendet wurde. Während Sie RSS-Feeds analysieren (wahrscheinlich über HTTP), sollten Sie die Codierung aus dem
charset
Parameter desContent-Type
HTTP-Headerfelds lesen . Wenn es nicht vorhanden ist, lesen Sie die Codierung aus demencoding
Attribut der XML-Verarbeitungsanweisung . Wenn dies ebenfalls fehlt, verwenden Sie UTF-8 wie in der Spezifikation definiert .Bearbeiten Hier ist, was ich wahrscheinlich tun würde:
Ich würde cURL verwenden , um die Antwort zu senden und abzurufen. Auf diese Weise können Sie bestimmte Headerfelder festlegen und auch den Antwortheader abrufen. Nach dem Abrufen der Antwort müssen Sie die HTTP-Antwort analysieren und in Header und Body aufteilen. Der Header sollte dann das
Content-Type
Headerfeld enthalten , das den MIME-Typ und (hoffentlich) auch dencharset
Parameter mit der Codierung / dem Zeichensatz enthält. Wenn nicht, analysieren wir den XML-PI auf das Vorhandensein desencoding
Attributs und erhalten von dort die Codierung. Wenn dies ebenfalls fehlt, definieren die XML-Spezifikationen die Verwendung von UTF-8 als Codierung.quelle
charset=
undencoding=
nicht nur an den entsprechenden Stellen. Und drittens überprüfen Sie nicht, ob die deklarierte Codierung akzeptiert wird.Das Erkennen der Codierung ist schwierig.
mb_detect_encoding
funktioniert durch Raten, basierend auf einer Reihe von Kandidaten, die Sie bestehen. In einigen Codierungen sind bestimmte Byte-Sequenzen ungültig und können daher zwischen verschiedenen Kandidaten unterscheiden. Leider gibt es viele Codierungen, bei denen dieselben Bytes gültig sind (aber unterschiedlich). In diesen Fällen gibt es keine Möglichkeit, die Codierung zu bestimmen. In diesen Fällen können Sie Ihre eigene Logik implementieren, um Vermutungen anzustellen. Beispielsweise haben Daten, die von einer japanischen Site stammen, möglicherweise eher eine japanische Codierung.Solange Sie nur mit westeuropäischen Sprachen beschäftigen, die drei großen Kodierungen zu berücksichtigen sind
utf-8
,iso-8859-1
undcp-1252
. Da dies für viele Plattformen Standardeinstellungen sind, wird auch am wahrscheinlichsten falsch darüber berichtet. Z.B. Wenn Leute unterschiedliche Codierungen verwenden, sind sie wahrscheinlich offen darüber, da sonst ihre Software sehr oft kaputt gehen würde. Daher ist es eine gute Strategie, dem Anbieter zu vertrauen, es sei denn, die Codierung wird als eine dieser drei angegeben. Sie sollten immer noch überprüfen, ob es tatsächlich gültig ist, indem Siemb_check_encoding
(beachten Sie, dass gültig nicht dasselbe ist wie sein - dieselbe Eingabe kann für viele Codierungen gültig sein). Wenn es eines davon ist, können Sie es verwendenmb_detect_encoding
zwischen ihnen zu unterscheiden. Zum Glück ist das ziemlich deterministisch; Sie müssen nur die richtige Erkennungssequenz verwendenUTF-8,ISO-8859-1,WINDOWS-1252
.Sobald Sie die Codierung erkannt haben, müssen Sie sie in Ihre interne Darstellung konvertieren (
UTF-8
ist die einzig vernünftige Wahl). Die Funktionutf8_encode
TransformationenISO-8859-1
aufUTF-8
, so kann es nur für diesen bestimmten Eingabetyp verwendet. Verwenden Sie für andere Codierungenmb_convert_encoding
.quelle
Eine wirklich gute Möglichkeit, eine Funktion zu implementieren
isUTF8
, finden Sie auf php.net :quelle
mb_check_encoding($string, 'UTF-8')
Dieses Cheatsheet listet einige häufige Vorbehalte im Zusammenhang mit der UTF-8-Handhabung in PHP auf: http://developer.loftdigital.com/blog/php-utf-8-cheatsheet
Diese Funktion zum Erkennen von Multibyte-Zeichen in einer Zeichenfolge kann sich ebenfalls als hilfreich erweisen ( Quelle ):
quelle
Ein bisschen Kopf hoch. Sie sagten, dass das "ß" in Ihrer Datenbank als "Ÿ" angezeigt werden sollte.
Dies liegt wahrscheinlich daran, dass Sie eine Datenbank mit Latin-1-Zeichencodierung verwenden oder dass Ihre PHP-MySQL-Verbindung möglicherweise falsch eingestellt ist. Dies bedeutet, dass P glaubt, dass MySQL UTF-8 verwendet, sodass Daten als UTF-8 gesendet werden Ihr MySQL glaubt jedoch, dass PHP Daten sendet, die als ISO 8859-1 codiert sind, und versucht daher möglicherweise erneut, Ihre gesendeten Daten als UTF-8 zu codieren, was zu solchen Problemen führt.
Schauen Sie sich mysql_set_charset an . Es kann Ihnen helfen.
quelle
Ihre Codierung sieht so aus, als hätten Sie zweimal in UTF-8 codiert . das heißt, von einer anderen Codierung in UTF-8 und wieder in UTF-8. Als ob Sie ISO 8859-1 hätten, von ISO 8859-1 nach UTF-8 konvertiert und die neue Zeichenfolge für eine weitere Konvertierung in UTF-8 als ISO 8859-1 behandelt hätten.
Hier ist ein Pseudocode von dem, was du getan hast:
Du solltest es versuchen:
mb_detect_encoding()
oder was auch immer Sie verwenden möchtenDies setzt voraus, dass Sie bei der "mittleren" Konvertierung ISO 8859-1 verwendet haben. Wenn Sie Windows-1252 verwendet haben, konvertieren Sie in Windows-1252 (latin1). Die ursprüngliche Quellcodierung ist nicht wichtig. Die, die Sie bei der fehlerhaften zweiten Konvertierung verwendet haben, ist.
Dies ist meine Vermutung, was passiert ist; Sie hätten kaum etwas anderes tun können, um vier Bytes anstelle eines erweiterten ASCII-Bytes zu erhalten.
Die deutsche Sprache verwendet auch ISO 8859-2 und Windows-1250 (Latein-2).
quelle
Das Interessante an
mb_detect_encoding
undmb_convert_encoding
ist, dass die Reihenfolge der von Ihnen vorgeschlagenen Codierungen eine Rolle spielt:Daher möchten Sie möglicherweise eine bestimmte Reihenfolge verwenden, wenn Sie die erwarteten Codierungen angeben. Beachten Sie jedoch, dass dies nicht kinderleicht ist.
quelle
if ($input_is_not_UTF8) $input_is_windows1252 = true;
. Siehe auch: html.spec.whatwg.org/multipage/…Sie müssen den Zeichensatz bei der Eingabe testen, da Antworten mit unterschiedlichen Codierungen codiert werden können.
Ich erzwinge, dass alle Inhalte an UTF-8 gesendet werden, indem die Erkennung und Übersetzung mit der folgenden Funktion durchgeführt wird:
Diese Routine wandelt alle PHP-Variablen, die vom Remote-Host kommen, in UTF-8 um.
Oder ignorieren Sie den Wert, wenn die Codierung nicht erkannt oder konvertiert werden konnte.
Sie können es an Ihre Bedürfnisse anpassen.
Rufen Sie es einfach auf, bevor Sie die Variablen verwenden.
quelle
Das Ausarbeiten der Zeichenkodierung von RSS-Feeds scheint kompliziert zu sein . Selbst normale Webseiten lassen ihre Kodierung oft aus oder lügen darüber.
Sie könnten also versuchen, die Codierung auf die richtige Weise zu erkennen und dann auf eine Form der automatischen Erkennung (Vermutung) zurückzugreifen.
quelle
charset
/encoding
Deklaration ist, wenn für: Beschreiben Sie die Codierung, in der die Daten codiert sind.Ich weiß, dass dies eine ältere Frage ist, aber ich denke, eine nützliche Antwort tut nie weh. Ich hatte Probleme mit der Codierung zwischen einer Desktopanwendung, SQLite und GET / POST-Variablen. Einige wären in UTF-8, andere in ASCII, und im Grunde würde alles durcheinander geraten, wenn fremde Charaktere involviert würden.
Hier ist meine Lösung. Es bereinigt Ihr GET / POST / REQUEST (ich habe Cookies weggelassen, aber Sie können sie bei Bedarf hinzufügen) bei jedem Laden der Seite vor der Verarbeitung. Es funktioniert gut in einem Header. PHP gibt Warnungen aus, wenn die Quellcodierung nicht automatisch erkannt werden kann. Daher werden diese Warnungen mit @ unterdrückt.
quelle
Ich habe seit Ewigkeiten nach Lösungen für die Codierung gesucht, und diese Seite ist wahrscheinlich das Ergebnis jahrelanger Suche! Ich habe einige der von Ihnen erwähnten Vorschläge getestet und hier sind meine Notizen:
Dies ist meine Testzeichenfolge:
Ich mache ein INSERT, um diese Zeichenfolge in einer Datenbank in einem Feld zu speichern, das als festgelegt ist
utf8_general_ci
Der Zeichensatz meiner Seite ist UTF-8.
Wenn ich einfach so ein INSERT mache, habe ich in meiner Datenbank einige Charaktere, die wahrscheinlich vom Mars kommen ...
Also muss ich sie in ein "vernünftiges" UTF-8 konvertieren. Ich habe es versucht
utf8_encode()
, aber immer noch dringen außerirdische Zeichen in meine Datenbank ein ...Also habe ich versucht, die
forceUTF8
auf Nummer 8 angegebene Funktion zu verwenden , aber in der Datenbank sieht die gespeicherte Zeichenfolge folgendermaßen aus:Nachdem ich weitere Informationen auf dieser Seite gesammelt und mit anderen Informationen auf anderen Seiten zusammengeführt habe, habe ich mein Problem mit dieser Lösung gelöst:
Jetzt habe ich in meiner Datenbank meine Zeichenfolge mit korrekter Codierung.
HINWEIS: Nur der zu beachtende Hinweis ist funktionsfähig
mysql_client_encoding
! Sie müssen mit der Datenbank verbunden sein, da diese Funktion eine Ressourcen-ID als Parameter benötigt.Aber gut, ich mache diese Neucodierung einfach vor meinem INSERT, also ist es für mich kein Problem.
quelle
UTF-8
Client-Codierung für MySQL? Würde keine manuelle Konvertierung auf diese Weise benötigenEs ist ganz einfach: Wenn Sie etwas, das nicht UTF-8 ist, müssen Sie codieren , dass in UTF-8.
Wenn Sie also einen bestimmten Feed abrufen, der ISO 8859-1 entspricht, analysieren Sie ihn
utf8_encode
.Wenn Sie jedoch einen UTF-8-Feed abrufen, müssen Sie nichts tun.
quelle
php.net/
mb_detect_encoding
oder
Ich weiß wirklich nicht, was die Ergebnisse sind, aber ich würde vorschlagen, dass Sie nur einige Ihrer Feeds mit unterschiedlichen Codierungen nehmen und versuchen, ob es
mb_detect_encoding
funktioniert oder nicht.update
auto ist die Abkürzung für "ASCII, JIS, UTF-8, EUC-JP, SJIS". Es gibt den erkannten Zeichensatz zurück, mit dem Sie die Zeichenfolge mit iconv in utf-8 konvertieren können .
Ich habe es nicht getestet, also keine Garantie. und vielleicht gibt es einen einfacheren Weg.
quelle
@harpax das hat bei mir funktioniert. In meinem Fall ist das gut genug:
quelle
Vergessen Sie nach dem Aussortieren Ihrer PHP-Skripte nicht, mysql mitzuteilen, welchen Zeichensatz Sie übergeben und erhalten möchten.
Beispiel: Zeichensatz utf8 setzen
Das Übergeben von utf8-Daten an eine latin1-Tabelle in einer latin1-E / A-Sitzung führt zu diesen unangenehmen Vogelfüßen. Ich sehe das jeden zweiten Tag in Oscommerce-Läden. Zurück und viertens scheint es richtig. Aber phpmyadmin wird die Wahrheit zeigen. Wenn Sie MySQL mitteilen, welchen Zeichensatz Sie übergeben, wird die Konvertierung von MySQL-Daten für Sie durchgeführt.
Wie man vorhandene verschlüsselte MySQL-Daten wiederherstellt, ist ein weiterer zu diskutierender Thread. :) :)
quelle
Diese Version ist für die deutsche Sprache, aber Sie können die $ CHARSETS und die $ TESTCHARS ändern
quelle
Holen Sie sich die Codierung aus den Headern und konvertieren Sie sie in utf-8.
quelle
Ÿ
ist Mojibake fürß
. In Ihrer Datenbank haben Sie möglicherweise hexSie sollten nicht jede Codierung / Decodierung Funktionen in PHP verwenden; Stattdessen sollten Sie die Datenbank und die Verbindung zu ihr korrekt einrichten.
Wenn MySQL beteiligt ist, lesen Sie: Probleme mit utf8-Zeichen; Was ich sehe, ist nicht das, was ich gespeichert habe
quelle
Ich finde hier eine Lösung http://deer.org.ua/2009/10/06/1/
Ich denke, dass @ eine schlechte Entscheidung ist, und nehme einige Änderungen an der Lösung von Deer.org.ua vor.
quelle
Die am häufigsten gewählte Antwort funktioniert nicht. Hier ist meins und hoffe es hilft.
quelle
Wenn Sie versuchen, mit mehreren Sprachen wie Japanisch und Koreanisch umzugehen, können Probleme auftreten. mb_convert_encoding mit dem Parameter 'auto' funktioniert nicht gut. Das Festlegen von mb_detect_order ('ASCII, UTF-8, JIS, EUC-JP, SJIS, EUC-KR, UHC') hilft nicht, da EUC- * falsch erkannt wird.
Ich kam zu dem Schluss, dass, solange Eingabezeichenfolgen aus HTML stammen, in einem Metaelement 'Zeichensatz' verwendet werden sollte. Ich verwende Simple HTML DOM Parser, weil es ungültiges HTML unterstützt.
Das folgende Snippet extrahiert das Titelelement von einer Webseite. Wenn Sie die gesamte Seite konvertieren möchten, möchten Sie möglicherweise einige Zeilen entfernen.
quelle
Ich hatte das gleiche Problem mit phpQuery ( ISO-8859-1 anstelle von UTF-8 ) und dieser Hack hat mir geholfen:
mb_internal_encoding('UTF-8')
,phpQuery::newDocumentHTML($html, 'utf-8')
,mbstring.internal_encoding
Und andere Manipulationen irgendeine Wirkung nicht nehmen.quelle
Versuchen Sie es ohne "Auto"
Das ist:
anstatt:
Weitere Informationen finden Sie hier: mb_detect_encoding
quelle