# Umlaute in PHP & HTML



## zer0 (6. Januar 2010)

Hallo, 

ich habe ein kleines Problem.
Die Umlaute die aus meiner MySQL Datenbank kommen werden wenn ich sie per PHP darstelle als Fragezeichen angezeigt (?) , jedoch die Umlaute die ich direkt in HTML eingebe, also die wo ich in die index.htm reinschreibe sind normal und werden angezeigt! Ich benutze dafür auch keine Codes wie &uuml; etc.
Habe mir natürlich schon überlegt eine funktion zubauen die Sonderzeichen in die HTML Codes umwandelt, aber trotzdem möchte ich wissen warum das nicht klappt.

Bei Wikipedia etc. im Quelltext stehen die Umlaute auch ohne Codes und werden richtig angezeigt. Beispiel: Schaut euch den Quelltext beim Ä bzw ä an!

Kann mir jemand dazu Rat geben!


----------



## Maik (6. Januar 2010)

Hi,

mit welchem Zeichensatz ist denn die DB hinterlegt?

Klingt so, wie wenn da ein Konflikt vorliegt (z.B. "UTF-8" vs. "ISO-8859-1").

Die genannte Wiki-Seite ist beispielsweise utf8-kodiert.

Möglicherweise hilft dir dies hier weiter:

utf8_encode
utf8_decode

mfg Maik


----------



## zer0 (7. Januar 2010)

Hallo,
Meine MySQL Datenbank hat den Zeichensatz UTF-8 (bzw. die Tabelle und Felder haben die Kollation "Latin_general_c1") und auch in meiner index.php steht beim <meta-Tag charset UTF-8. Also sollte es ja eigentlich nicht daran liegen. Ich schau mir mal deine Links an!

Würdest du den sagen das es allgemein besser ist Sonderzeichen in die jeweiligen HTML Codes umzuwanndeln?

Gruß


----------



## Sven Mintel (7. Januar 2010)

Hört sich an, als müsstest du den Zeichensatz der DB-Verbindung noch auf UTF8 setzen:


```
SET names utf8
```


----------



## SilentWarrior (7. Januar 2010)

zer0 hat gesagt.:


> in meiner index.php steht beim <meta-Tag charset UTF-8.


Der Meta-Tag ist in diesem Fall relativ nutzlos; wichtig ist die Information, die im Header steht. Setz mal folgendes ganz an den Anfang deines PHP-Dokuments:


```
header('Content-Type: text/html; charset=utf-8');
```


----------



## Sven Mintel (7. Januar 2010)

SilentWarrior hat gesagt.:


> Der Meta-Tag ist in diesem Fall relativ nutzlos; wichtig ist die Information, die im Header steht.



Naja, ich würd sagen, entscheidend ist vor allem, wie die Ausgabe an den Browser codiert ist(in welchem Zeichensatz das Skript gespeichert ist oder ob die Ausgabe bspw. per utf8_encode() codiert wurde)...das scheint ja UTF8 zu sein, da die Ausgabe, die nicht aus der Datenbank kommt in Ordnung ist.


----------



## zer0 (7. Januar 2010)

Okay, sobald ich daheim bin probiere ich das mal aus! 
Aber was meint ihr, ist es allgemein besser Sonderzeichen in HTL Codes umzuwandeln?


----------



## Sven Mintel (7. Januar 2010)

Naja, damit würdest du zwar das Zeichensatzkuddelmuddel flickschustern, aber das verbraucht mehr Speicherplatz in der DB/auf dem Server und verursacht mehr Traffic.

Und wenn du deine Daten mal für etwas anderes als HTML-Dokumente benötigst, musst du sie wieder decodieren und stehst vor dem selben Problem.


----------



## SilentWarrior (7. Januar 2010)

Sven Mintel hat gesagt.:


> Naja, ich würd sagen, entscheidend ist vor allem, wie die Ausgabe an den Browser codiert ist(in welchem Zeichensatz das Skript gespeichert ist oder ob die Ausgabe bspw. per utf8_encode() codiert wurde)...das scheint ja UTF8 zu sein, da die Ausgabe, die nicht aus der Datenbank kommt in Ordnung ist.


Natürlich ist es wichtig, wie die Ausgabe codiert ist. Aber der Browser muss diese Codierung ja auch kennen. Und meines Wissens benutzen die meisten Browser nach wie vor ISO-8859-1 als Standard-Codierung, womit es dann natürlich zu Problemen kommt.



zer0 hat gesagt.:


> Okay, sobald ich daheim bin probiere ich das mal aus!
> Aber was meint ihr, ist es allgemein besser Sonderzeichen in HTL Codes umzuwandeln?


Das hängt davon ab, welche Codierung du verwendest. Bei Unicode müssen nur die allerwenigsten Zeichen codiert werden (ich glaube nur <, >, & und "). Das ist natürlich schon sehr praktisch.


----------



## zer0 (7. Januar 2010)

Also, folgende Daten habe ich & es geht immernoch nicht:
MySQL-Zeichensatz:  UTF-8 Unicode (utf8) 
Zeichensatz / Kollation der MySQL-Verbindung: utf8_general_c1
Tabellenkollation: utf8_general_ci
Die betroffenen Felder sind auch alles: utf8_general_ci

Trotzdem geht es immernoch nicht! Ausserdem, was für Kollationen benutzt ihr so üblich?

##EDIT##

Hmm, also mit utf8_encode(); klappts! Nur würde ich gerne wissen ob das ein allgemeines Problem das auch in anderen Seiten auftritt bzw. wo genau mein fehler liegt?


----------



## PHP-HELPER-2010 (7. Januar 2010)

Setze zum testen die Kollation der Tabelle und Spalten auf "latin1_german2_ci".
Die Kollation der MySQL-Verbindung belasse auf "utf8_general_ci".

Gruß

PHP-HELPER-2010


----------



## Sven Mintel (7. Januar 2010)

zer0 hat gesagt.:


> Also, folgende Daten habe ich & es geht immernoch nicht:
> ........
> Zeichensatz / Kollation der MySQL-Verbindung: utf8_general_c1
> ..........



Gehe ich recht in der Annahme, dass du diese Info von PHPMyAdmin hast?

Falls ja...das bedeutet erstmal, dass bei PHPMyAdmin die Verbindung unter UTF8 läuft...was noch lange nicht bedeutet, dass dies der Server-Standard ist(und somit in deinen Skripten der Fall ist)

Gehe mal auf der PHPMyAdmin-Startseite auf den Tab "Variablen"....dort findest du die Systemvariablen.
Poste mal was dort bei
character set client  
character set connection 
character set database 	
character set results 	
character set server

...steht.

Ansonsten: es könnte sein, dass du die Daten "reparieren" musst...wenn sie falsch eingetragen wurden, ändert eine nachträgliche Änderung der Einstellungen auch nichts daran.


----------



## zer0 (7. Januar 2010)

Hier:


```
character set client  	utf8
(Globaler Wert) 	latin1
character set connection 	utf8
(Globaler Wert) 	latin1
character set database 	latin1
character set filesystem 	binary
character set results 	utf8
(Globaler Wert) 	latin1
character set server 	latin1
character set system 	utf8
character sets dir 	C:\Xampp\xampp\mysql\share\charsets\
collation connection 	utf8_general_ci
(Globaler Wert) 	latin1_swedish_ci
collation database 	latin1_swedish_ci
collation server 	latin1_swedish_ci
```


----------



## boast (8. Januar 2010)

zer0 hat gesagt.:


> Hmm, also mit utf8_encode(); klappts! Nur würde ich gerne wissen ob das ein allgemeines Problem das auch in anderen Seiten auftritt bzw. wo genau mein fehler liegt?



Also ich sag jetzt mal (ganz unverbindlich), dass es an den vorherigen Einstellungen lag: Wenn Du Sonderzeichen erst mit latin_xxx speicherst und dann einfach den Zeichensatz der Spalte / Tabelle / Datenbank änderst, änder sich an deinen bereits gespeicherten Daten (und das muss so sein) nichts - Du kannst zwar jetzt "äöü"s speichern, aber die alten Einträge werden immernoch fehlerhaft sein..

Meiner Meinung nach, solltest Du alles so belassen, wie es "jetzt" funktioniert und beim nächsten Projekt einfach daran denken: konsistent, konsequent, komme was wolle: UTF-8 / UNICODE  Das wirst du bei Deinen nächsten Projekten bestimmt schätzen.

Bei phpMyAdmin kannst Du gleich am Anfang auf der Übersichtseite und jedes mal, wenn Du eine neue Datenbank bzw. Tabell bzw. Spalte erstellst, den Zeichensatz wählen.

Kurz: machs mit utf8_encode(), und das nächste mal gleich mit den "richtigen" Datenbank Einstellungen.

HappyBirthday2Me und gute Nacht


----------



## Sven Mintel (8. Januar 2010)

Jo, da stehen die 3 entscheidenden Variablen als Systemstandard auf latin1 und nicht auf UTF8

character set client  	utf8
*(Globaler Wert) 	latin1*
character set connection 	utf8
*(Globaler Wert) 	latin1*
character set results 	utf8
*(Globaler Wert) 	latin1*

Das rot markierte sind die Werte für die Sitzung, diese dürften von PHPMyAdmin gesetzt werden.
Genau dasselbe musst du auch machen....zur Datenbank verbinden und als allererstes das bereits von mir erwähnte Query absetzen

```
SET names utf8
```
...das setzt diese 3 Variablen für die Sitzung auf UTF8


----------



## zer0 (8. Januar 2010)

Also erstmal vielen Dank an alle! 

@boast: So werde ich das auch mal mache. Aber da mein Projekt bis jetzt auf localhost mit XAMPP lief, es aber eigentlich auf meinem Webspace laufen soll, werde ich versuchen die Einstellungen von Anfang an so zusetzten das es klappt. Und alles gute von mir 

@Sven diese Sitzungsvariablen (die roten) kann ich durch den Query setzen. Kann ich den auch den globalen Wert einfach auf UTF8 setzten, und das mir so ersparen?


----------



## DrEvil (8. Januar 2010)

Ja hallo,
ich misch mich hier mal ein, denn ich habe gerade das gleiche Problem... und ich bin kurz vorm Verzweifeln...

Ich speichere mittels Formular Daten in meiner Datenbank.

Ich habe ALLE Collations die ich finden konnte und mir zugänglich waren (habe keinen eigenen Server) - d.h. Datenbank, Tabelle, Felder, MySQL-Verbindungen der Datenbank auf "utf_general_ci" gesetzt

Ich habe

```
<form accept-charset="utf-8" action="index.php" method="post" name="Name">
```
eingefügt.

Ich habe sogar mal versucht den Charset des HTML-Metas auf "utf_general_ci" zu setzen. Das hat natürlich nicht geklappt, da wurde dann nich mal mehr die Umlaute der Seite korrekt angezeigt...
Jetzt ist Meta-Tag wieder

```
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
```

Ich würde es echt gerne mal korrekt hinbekommen - aber es klappt einfach nicht.


----------



## Sven Mintel (8. Januar 2010)

zer0 hat gesagt.:


> @Sven diese Sitzungsvariablen (die roten) kann ich durch den Query setzen. Kann ich den auch den globalen Wert einfach auf UTF8 setzten, und das mir so ersparen?



Sofern du Zugriff auf die my.cnf hast, kannst du das ändern.


```
default-character-set=utf8
```


----------



## zer0 (8. Januar 2010)

Sven Mintel hat gesagt.:


> Sofern du Zugriff auf die my.cnf hast, kannst du das ändern.
> 
> 
> ```
> ...



Das denke ich weniger das ich Zugriff darauf habe  Aber wenn ich drauf achte das ich beim erstellen von Datenbanken, Tabellen etc. ausschließlich UTF-8 benutze ist das Problem ja eigentlich behoben 

@DrEvil: In den vorherigen Posts findest du den Beitrag das sich durch nachträgliches ändern der Kollation etc. die Daten der Datenbank trotzdem nicht ändern! Vllt liegt es ja daran!

#EDIT:
Achja, eine Methode wäre ja das ich zunächst mein Inhalt aus der Datenbank mit *mb_detect_encoding()* prüfe und dann falls es ISO-8859-1 ist, utf8_encode() anwende, oder seh ich das falsch?


----------



## Sven Mintel (8. Januar 2010)

zer0 hat gesagt.:


> Das denke ich weniger das ich Zugriff darauf habe  Aber wenn ich drauf achte das ich beim erstellen von Datenbanken, Tabellen etc. ausschließlich UTF-8 benutze ist das Problem ja eigentlich behoben



Nö, eben nicht.
Diese 3 Variablen müssen halt auch die entsprechenden Werte haben, und da hat der Datensatz der Tabellen keinen Einfluss drauf.

Es sollte aber nicht sehr umständlich zu bewerkstelligen sein, in seiner DB-Klasse dies kleine Query einzubauen


----------



## zer0 (8. Januar 2010)

Sven Mintel hat gesagt.:


> Nö, eben nicht.
> Diese 3 Variablen müssen halt auch die entsprechenden Werte haben, und da hat der Datensatz der Tabellen keinen Einfluss drauf.
> 
> Es sollte aber nicht sehr umständlich zu bewerkstelligen sein, in seiner DB-Klasse dies kleine Query einzubauen



Achso, das ist natürlich blöd!

Eigentlich nicht, aber wenn ich PDO benutze? Sollte ich dann beim erstellen des PDO Objekt ein Query mit "SET names utf8"abstezten? Und mit was soll ich den "names" ersetzten?


----------



## Sven Mintel (8. Januar 2010)

zer0 hat gesagt.:


> Achso, das ist natürlich blöd!
> 
> Eigentlich nicht, aber wenn ich PDO benutze? Sollte ich dann beim erstellen des PDO Objekt ein Query mit "SET names utf8"abstezten? Und mit was soll ich den "names" ersetzten?



Jo, PDO erzeugen und als erstes das Query. Das "names" musst du nicht ersetzen, das Query kann so bleiben, wie ich es gepostet habe(mal vom Zeichensatz abgesehen, falls du einen anderen möchtest).


----------



## zer0 (8. Januar 2010)

Sven Mintel hat gesagt.:


> Jo, PDO erzeugen und als erstes das Query. Das "names" musst du nicht ersetzen, das Query kann so bleiben, wie ich es gepostet habe(mal vom Zeichensatz abgesehen, falls du einen anderen möchtest).



Okay, gut, vielen Dank!

Der Query setzt ja die Variablen für diese Sitzung auf utf8, aber trotzdem müssen meine Tabelle auch den UTF-8 Zeichensatz haben, oder?


----------



## Sven Mintel (8. Januar 2010)

zer0 hat gesagt.:


> Okay, gut, vielen Dank!
> 
> Der Query setzt ja die Variablen für diese Sitzung auf utf8, aber trotzdem müssen meine Tabelle auch den UTF-8 Zeichensatz haben, oder?



Jo, das wäre schon gut, ist aber nicht unbedingt zwingend.

MySQL geht da folgendermaßen vor:
Es bekommt die Daten beim Eintragen in irgendeinem Zeichensatz.
Welcher das angeblich ist, bestimmt *character set client* . Der Client sollte also auch wirklich die Daten in dem korrekten Zeichensatz abschicken(tut er bei dir ja, soweit ich es verstanden habe).

MySQL nimmt die Daten nun entgegen, und konvertiert sie, falls *character set client* nicht mit dem Zeichensatz der Tabelle übereinstimmt, zu dem Zeichensatz der Tabelle...so werden sie dann auch eingetragen.

Beim Abholen der Daten geht es umgekehrt:
MySQL holt die Daten aus der Tabelle. In welchem Zeichensatz der Client die Daten erhält, bestimmt *character set results*.
Ist dieser Zeichensatz wiederum anders, als der der Tabelle, werden die Daten zu *character set results* konvertiert....und so an den Clienten gesendet.

Dies ganze Konvertieren kann jedoch Probleme in sich bergen:


			
				http://dev.mysql.com/doc/refman/5.1/de/charset-connection.html hat gesagt.:
			
		

> Die Konvertierung kann verlustbehaftet sein, wenn Zeichen verwendet werden, die nicht in beiden Zeichensätzen vorhanden sind.


daher bist du auf der ganz sicheren Seite, wenn alle beteiligten Parteien den selben Zeichensatz verwenden.


----------



## zer0 (8. Januar 2010)

Okay, jetzt bin ich mir doch fast sicher das ich alles verstanden habe 

Vielen Dank an dich & natürlich auch an alle anderen!


----------



## zer0 (9. Januar 2010)

So bevor ich ein neues Thema aufmache, schreib ich es hier rein! Habe schon wieder ein Umlaute-Problem -_- Diesmal ohne MySQL sondern nur PHP!

Mein Code sieht wie folgt aus:

```
header('Content-Type: text/html; charset=utf-8');

    $string = strtolower('8025 Hallo an alle: Über mich!');
    $return = '';

    $search  = array('ä', 'ö', 'ü', 'ß');
    $replace = array('ae', 'oe', 'ue', 'ss');
    $string  = str_replace($search, $replace, $string);

    for($i = 0; $i < strlen($string); $i++) {
        if($string{$i} == ' ') {
            $return .= '-';
        } elseif(preg_match('/[0-9a-z]/', $string{$i})) {
            $return .= $string{$i};
        }
    }

    echo $return;
```

Wie ihr seht, ich will Strings umschreiben! Nur macht er aus dem 'ü' in $string ü => ãœ oder mit UTF-8 also der Header Information wieder das schöne Fragezeichen ?

Das komische, ich habe es auch versucht mit Daten aus der DB, die normalerweise korrekt angezeigt werden! Weiß dazu vllt jemand etwas?


----------



## TvP (9. Januar 2010)

Oh da kann ich vielleicht helfen.. 
Nimm die Funktion php.net/strtr


```
$dt = get_html_translation_table(HTML_ENTITIES+HTML_SPECIALCHARS);
	    $tt = strtr($tt,$dt);
```

Wobei in $tt der Text und in $dt die zu ändernden Werte sind.
HTML_ENTITIES kannst du weglassen, du möchtest ja nur die Buchstaben übersetzt. wissen.
---------------------------------------------

Ich hab das mal fix mit deiner Funktion kombiniert. Du musst zuerst deine $return bilden, keine Ahnung was das darstellen soll  *klär mich mal auf * und danach die Umwandlung vornehmen.
Dann dürfte es funtkionieren


----------



## Sven Mintel (9. Januar 2010)

Die Ursache dürfte sein, dass die PHP-String-Funktionen derzeit noch standardmässig mit Latin1 arbeiten.

Verwende stattdessen die MB-String-Funktiionen


----------



## zer0 (9. Januar 2010)

Sven Mintel hat gesagt.:


> Die Ursache dürfte sein, dass die PHP-String-Funktionen derzeit noch standardmässig mit Latin1 arbeiten.
> 
> Verwende stattdessen die MB-String-Funktiionen



Habe ich schon probiert! Er bringt mir bei mb_detect_encoding($string); UTF-8 und auch mit der Konvertier Funktion hat es nicht geklappt!

Fragt mich jetzt nicht warum, aber aufeinmal gehts!
Ich habe zu erst diese Funktion von php.net ausprobiert:

```
<?php

function normalize ($string) {
    $table = array(
        'Š'=>'S', 'š'=>'s', '?'=>'Dj', '?'=>'dj', 'Ž'=>'Z', 'ž'=>'z', '?'=>'C', '?'=>'c', '?'=>'C', '?'=>'c',
        'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'A', 'Å'=>'A', 'Æ'=>'A', 'Ç'=>'C', 'È'=>'E', 'É'=>'E',
        'Ê'=>'E', 'Ë'=>'E', 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I', 'Ï'=>'I', 'Ñ'=>'N', 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O',
        'Õ'=>'O', 'Ö'=>'O', 'Ø'=>'O', 'Ù'=>'U', 'Ú'=>'U', 'Û'=>'U', 'Ü'=>'U', 'Ý'=>'Y', 'Þ'=>'B', 'ß'=>'Ss',
        'à'=>'a', 'á'=>'a', 'â'=>'a', 'ã'=>'a', 'ä'=>'a', 'å'=>'a', 'æ'=>'a', 'ç'=>'c', 'è'=>'e', 'é'=>'e',
        'ê'=>'e', 'ë'=>'e', 'ì'=>'i', 'í'=>'i', 'î'=>'i', 'ï'=>'i', 'ð'=>'o', 'ñ'=>'n', 'ò'=>'o', 'ó'=>'o',
        'ô'=>'o', 'õ'=>'o', 'ö'=>'o', 'ø'=>'o', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'ý'=>'y', 'ý'=>'y', 'þ'=>'b',
        'ÿ'=>'y', '?'=>'R', '?'=>'r',
    );
   
    return strtr($string, $table);
}

?>
```

Aber dann gings auch ohne Sie! Naja hoffen wir mal  das es so bleibt!  Danke trotzdem!

#EDIT:
Kleine Info noch, sobald ich den String mit strtolower() behandle passiert der Fehler wieder! Das umgehe ich nun einfach!


----------

