Wie vergleiche ich PHP Variablen mit unterschiedlicher Codierung?
Hallo liebe Community.
Ich suche die Lösung für ein Problem bei der Programmierung mit PHP und Variablen.
Ich möchte gerne einen Wert, den ich über mysqli abgerufen habe mit einer Variable aus einem Array vergleichen.
Das Problem dabei ist, dass bei Umlauten und Sonderzeichen das Programm nicht mitmacht. Die beiden verglichenen Werte müssten gleich sein, werden aber nicht als gleich erkannt.
Hier mein Beispiel:
Datenbank:
id --- vorname --- nachname
1 --- Sabrina --- Müller
PHP:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
(Hier ein PHP Abschnitt zur Eintragung in die Datenbank, also demnach auch in UTF8 codiert)
$test = array("Sabrina","Müller");
$result = mysqli_query($datenbank,"SELECT vorname, nachname FROM telefonbuch WHERE id='1'");
while($row=mysqli_fetch_array($result,MYSQLI_ASSOC)) {
if($row['nachname']==$test[1])
echo "Erfolg";
else
echo "Kein Erfolg";
}
Ergebnis:
Wenn ich die Seite so aufrufe, kommt "Kein Erfolg".
Die Datenbank umfasst mehr Einträge, also alles andere ist richtig programmiert. Alles hat "Erfolg", nur die Einträge mit ä,ö,ü,ß,@, etc. haben keinen Erfolg.
Auch if($row['nachname']=='Müller') → Kein Erfolg
Auch if($row['nachname']=='Müller') → Kein Erfolg
Auch wenn ich beide Werte vorher in Variablen packe → Kein Erfolg
Ein Test mit:
echo mb_detect_encoding($str)
Ergibt bei:
$row['nachname'] → UTF-8
$test[1] → ASCII
Wieso kann ich diese beiden Variablen nicht miteinander vergleichen und was kann ich tun, um dieses Problem mit den Umlauten zu lösen?
Vielen Dank für jede Hilfe.
Liebe Grüße =)
3 Antworten
1 --- Sabrina --- Müller
Ok, also wenn in der Datenbank wirklich die Umlaute und anderen nicht-ASCII-Zeichen als HTML-Entities stehen, dann ist die Datenbank Murks. Die Datenbank sollte UTF-8-kodiert sein und dann steht dort ganz normal „Müller“ im Datensatz drin.
$row['nachname'] → UTF-8
Also offenbar ist die Datenbank ja doch UTF-8-kodiert. Weshalb denkst du, dass der Nachname als „Müller“ in der Datenbank steht?
Wieso kann ich diese beiden Variablen nicht miteinander vergleichen und was kann ich tun, um dieses Problem mit den Umlauten zu lösen?
Nun, die einfachste Möglichkeit ist, konsequent mit UTF-8 zu arbeiten. Also Datenbank, Skripte und Webseite alle UTF-8 kodieren. Dann musst du kaum aufpassen – nur bei einigen PHP-Funktionen, für die es eine extra MultiByte-Funktion gibt.
In deinem Fall reicht es vermutlich aus, überall „Müller“ zu schreiben und das PHP-Script im Editor UTF-8-kodiert zu speichern. Dann klappt auch der Vergleich.
Aber ich dachte das Script wäre bereits UTF-8 codiert, indem ich diesen Tag hier benutze:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
Oder muss ich noch etwas zusätzliches machen?
Achso man kann es auch in der Codierung speichern? Ich dachte du meinst den Programm Code. Okay und wie mache ich das?
Und geht das mit HTML Editor Phase 5? Denn diesen benutze ich zum Programmieren, und da ich mit diesem gut klar komme würde ich den auch gerne beibehalten. Oder muss ich jetzt was anderes nehmen?
Phase 5 hat vor 14 Jahren das letzte kleine Update bekommen und ist soweit ich das sehe nicht Unicode-fähig. Entsprechend kann ich dir nur abraten, diesen Editor weiter zu nutzen, da er aktuellen Anforderungen nicht mehr genügt.
Unter Windows kennen ich mich nicht so aus aber Visual Studio Code ist ein guter kostenloser Editor und auch Notepad++ wird oft genannt. In beiden kannst du die Zeichenkodierung einstellen.
Achso man kann es auch in der Codierung speichern?
Man muss es an beiden Stellen machen. Im Editor muss die Datei mit der richtigen Zeichenkodierung – für alle Dateien – gespeichert werden und diese Kodierung gibt man dann im HTML-Dokument mit an, damit der Browser dies nicht raten muss.
Am einfachsten gibst du es für HTML5-Dokumente dann so an:
<meta charset="utf-8">
Aber wie gesagt, HTML-Datei, PHP-Skripte und Datenbank sollten dann auch UTF-8-kodiert sein.
Danke vielmals für deine Hilfe.
Ich habe das jetzt mal mit dem Notepad versucht, und tatsächlich, es funktioniert. Wenn ich das aber wieder mit Phase 5 öffne, sehe ich anstelle von Ü's so komische Zeichen: Müller
Das heißt, der ist wohl wirklich nicht UTF8 fähig.
Ich werde mich wohl nach einem neuen Editor umschauen müssen. Die beiden von dir genannten werde ich mir zuerst anschauen. Ich hoffe ich finde den für mich geeigneten. Aber nun weiß ich wo das Problem lag und das Programm funktioniert so wieder.
Vielen Dank nochmal :)
Aber wenn wir schonmal dabei sind, eine Frage noch: Also meine Datenbank ist zwar UTF8 codiert, da ich ja aber mal ein altes Programm hatte mit den HTML Entities und nun das neue Programm ohne, ist ein Teil der Datensätze mit "Müller" und ein anderer Teil mit "Müller".
Muss ich nun jeden einzelnen Eintrag durchgehen und bearbeiten oder kann man irgendetwas machen, dass alles auf einen Schlag wieder in "Müller" geändert wird?
Da musst du zumindest einmal deine Datenbank einmal komplett bereinigen. Sofern es sich nur um deine zwei Spalten und Umlaute handelt, würde ich es bspw. in phpMyAdmin einfach nach und nach pro Spalte und Zeichen machen:
UPDATE telefonbuch SET nachname = REPLACE(nachname, 'ü', 'ü');
Das ersetzt in der Tabelle telefonbuch in der Spalte nachname das HTML-Entity ü mit einem ü. Das musst du jetzt nacheinander für alle bei dir vorkommenden Umlaute machen:
- Ü → Ü
- ä → ä
- Ä → Ä
- ß → ß
- usw.
Dann noch mal alles für vorname und ggf. andere Spalten.
Sichere vorher aber deine Datenbank und überprüfe die Einträge danach. Fehler lassen sich nicht so einfach rückgängig machen und wenn man nicht aufpasst, zerschießt man leicht die Datenbank.
Okay dann werde ich das benutzen und vorher natürlich alles sichern. Vielen Dank nochmal :)
Abgesehen davon, dass es natürlich besser ist, alles nur noch als UTF-8 zu machen, gibt es in php ja auch die Funktion utf8_encode (veraltet) bzw. mb_convert_encoding
Ja die Codierung war ungleich bei mir, ich habe die Lösung dafür nun gefunden, es alles in UTF8 zu speichern. Danke dir
Mein erster Rat wäre, dass du möglichst nur mit einer einheitlichen Zeichenkodierung arbeitest. UTF-8 bietet sich hierbei als stabile Kodierung, die eine große Anzahl an Zeichen unterstützt, sehr gut an.
Das bedeutet, du gibst für dein HTML-Dokument eine Zeichenkodierung im head-Bereich an:
<meta charset="utf-8">
und legst für deine Datenbank utf8mb4 fest. Beim Verbindungsaufbau mit der Datenbank kann man zusätzlich die Kodierung noch einmal explizit definieren:
$mysqli->set_charset('utf8mb4');
HTML-Entities (wie ü o.ä.) für Sonderzeichen, die du mit UTF-8 bereits abbilden kannst, solltest du eher vermeiden.
Wenn deine Datenbank nun schon Daten mit anderer Zeichenkodierung oder Strings mit HTML-Entities enthält, wäre es das beste, du würdest diese Daten noch einmal transformieren.
- Bei unterschiedlicher Kodierung: Die Daten exportieren und in eine neue Datenbank mit utf8mb4-Kodierung importieren.
- Bei Einsatz von HTML-Entities: Die Daten der Datenbank durchlaufen und HTML-Entities mittels String-Funktionen ersetzen.
Ja es war tatsächlich die Codierung, danke für deine Hilfe.
Vielen Dank für deine Hilfe.
Ich habe festgestellt, dass die Datensätze in meiner Datenbank verschieden sind. Ich hatte mal ein altes Programm, das hat noch mit $nachname = htmlentities($_REQUEST['nachname']); gearbeitet und dadurch die Einträge in ü eingetragen. Das neue PHP Dokument hat das nicht mehr und die Einträge in "Müller" normal geschrieben. Das sehe ich jetzt erst so richtig. MUss ich alles mal vereinheitlichen.
Aber nun ergibt sich weiterhin das gleiche Problem. Wenn ich jetzt den Eintrag "Müller" aus der Datenbank mit "Müller" aus dem Array vergleichen möchte, ist er immer noch ungleich. Egal ob ich im Array "Müller" oder "Müller" stehen habe, in beiden Fällen ungleich.
Der array (genau wie eine $test Variable für den Fall dass es mit dem Array zusammenhängt) sind laut mb_detect_encoding immer noch ASCII.
Wie kann ich das vereinheitlichen, dass auch die Variablen nun UTF 8 sind und ich Müller mit Müller vergleichen kann?