[TYPO3-german] setDBinit

Michael Stucki michael at typo3.org
Wed Feb 18 11:06:13 CET 2009


Hallo Peter!

Peter Niederlag schrieb:
>>> Leider ist das ein sehr weit verbreiteter Irrglaube!
>>>
>>> ---------------------------------------------------------------- 
>>> Das MySQL-Modul von PHP benutzt IMMER latin1 als Zeichensatz für
>>> die Verbindung zw. PHP und MySQL! 
>>> ----------------------------------------------------------------

Ich glaube wir sind uns einig über die Funktion von MySQL. Ich finde es
jedoch falsch, wenn man "IMMER" schreibt und gleichzeitig weiss, dass
das nicht der Fall ist. Nicht alle Nutzer sind Kunde eines Shared
Hostings. Viele User haben Zugriff auf die Serverkonfiguration bzw.
hosten die Seiten sogar selber. Genau darum wollte ich das präzisieren.

>> Das wäre mir neu.
> 
> Gut, dann nochmal ganz akademisch genau. ;)
> Das MySQL-Modul von PHP benutzt immer den Zeichensatz, mit dem libmysql
> bzw. MySQL kompilliert wurde(default=latin1)! vgl.: [1] [2]
> 
> Fakt ist jedenfalls, dass der Zeichensatz MySQL-Verbindung von PHP aus
> in 98% der Fälle 'latin1' ist, weil das nur durch eine dieser drei
> Möglichkeiten zu ändern ist:
> 
> 1. Kompillieren der libmysql-Bibliothek mit './configure
> --with-charset=utf8'
> 2. my.cnf: 'skip-character-set-client-handshake'
> 3. my.cnf: 'init-connect=SET NAMES `utf8`' (o.ä.)
> 
> IMO ist das alles nichts für den üblichen Hausgebrauch!
> Daneben beeinflusst es möglicherweise andere Applikation, die noch mit
> dem MySQL-Server arbeiten, und evtl. nicht auf solche ungewöhnlichen
> Settings vorbereitet sind.

Stimmt, aber dann trifft es eben nicht IMMER zu und man kann das sehr
wohl kontrollieren, siehe oben.

>>> D.h. MySQL rekodiert ggf. automatisch zw. dem Zeichensatz der
>>> Verbindung und der Datenbank. Da das sowohl bei der Abfrage, als
>>> auch beim Rückliefern des Ergebnis passiert, merkt man das
>>> innerhalb TYPO nicht!
>>>
>>> Sobald jedoch eine andere Anwendung (phpmyadmin, o.a.) mit der
>>> Datenbank arbeitet fällt das Problem auf (Im übrigen auch bei einem
>>> Backup mit mysqldump).
>> Das wäre der Fall wenn man setDBinit nutzen würde, weil das nur von 
>> TYPO3 genutzt würde.
> 
> Warum sollte es mit setDBinit Probleme geben? Hast Du da ein Beispiel?

Jemand verwendet setDBinit, setzt die MySQL Verbindung für die
TYPO3-Verbindung auf "UTF-8". Danach ruft er ein externes (nicht das in
TYPO3 integrierte) phpMyAdmin auf, möglicherweise noch mit einem anderen
DB-User. Diese Verbindung wird den Standard nutzen, d.h. "latin1".

Aus dem Grund halte ich setDBinit für einen Workaround, aber nicht für
die saubere Lösung. Man sollte wenn möglich den Zeichensatz immer global
festlegen (d.h. in my.cnf).

> Probleme entstehen dann, wenn die Zeichensatz-Variablen, die gesetzt
> sind, nicht zu dem faktisch verwendten Zeichensatz der Anwendung passen.

Genau.

>> Aber wenn Server und PHP schon mit UTF-8 laufen gibt's da keine
>> Probleme.
> 
> Was heisst denn "Server und PHP schon mit UTF-8 laufen" genau? Genau da
> im Detail liegt doch der Hase im Pfeffer!

Indem der Zeichensatz in my.cnf festgelegt wird, siehe letzte Mail von mir.

>>> Merke: forceCharset immer nur zusammen mit setDBinit verwenden!
>>> Sonst gibt es
>>> a) doppelt UTF-8 kodierte Daten bei einer ut8-8 Datenbank oder
>>> b) UTF-8 kodierte Daten in einer Datenbank wo latin1 vorne draufsteht.
>> All das ist möglich, aber nicht die Regel.
> 
> Dutzende von Praxisbeispielen sagen anderes! Sobald forceCharset ohne
> weitere Massnahmen (siehe Anfang dieser Mail) gesetzt wird, passiert a)
> oder b)

Natürlich hast du recht, aber setDBinit ist nicht die einzige Möglichkeit.

Und das verwirrt z.B. mich wenn ich es nicht besser wüsste ;-)

> Laut [3] wirkt sich 'character-set-server = utf8' nur auf CREATE aus.
> Das habe ich bisher auch immer geglaubt. Aber, bei gleichzeitiger
> Verwendung  von 'skip--character-set-client-handshake' hat es nach [4]
> dann tatsächlich auch noch die Auswirkung dass es den Zeichensatz der
> Verbindung festlegt. Damit ist "They have no other purpose" auf [3]
> eigentlich falsch. ;)

Interessant. Aber solange die Funktion sich so verhält wie ich das
erwarte kann mir das recht sein.

>>> P.S.: es gibt noch eine alternative/analoge Lösung zu setDBinit für
>>> den Mysql-Server, die ich aber nicht empfehlen würde: 
>>> #init-connect=SET NAMES `utf8`
>> Das würde vermutlich das gleiche tun wie obenstehende Konfiguration.
> 
> Es ist eine der drei Möglichkeiten JEDEN Nutzer des MySQL-Servers zu
> zwingen standardmäßig utf8 zu verwenden (Wobei die Anwendung das
> anschließend nochmal selbst ändern kann).

Stimmt. Gleich wie bei setDBinit kostet das jedoch bei jedem
Verbindungsaufbau ein zusätzliches Query. Darum würde ich, nach
Möglichkeit, die Variante mit skip-character-set-client-handshake verwenden.

>> Warum würdest du das nicht empfehlen?
> 
> Weil jeweils nur die Anwendung/der Client weiss, in welchem Zeichensatz
> sie Ihre Daten abliefert, und in welchem Zeichensatz sie das Ergebnis
> erwartet! Und ein MySQL-Server, der wirklich ÜBERALL durchgängig utf8
> verwendet, eher die Aussnahme, denn die Regel ist. Und, wenn eine
> Anwendung failsafe sein soll, muss sie das ganze so oder so nochmal
> prüfen und ggf. ändern. Dafür gibt es ja die 'character_set_%' Variablen. ;)

Ja. Was man machen könnte ist in TYPO3 eine art Autodetection einzubauen
und setDBinit damit zu ersetzen. Allerdings geht das erneut auf Kosten
eines bzw. von zwei weiteren Queries bei jedem Verbindungsaufbau...

Liebe Grüsse
- michael
-- 
Use a newsreader! Check out
http://typo3.org/community/mailing-lists/use-a-news-reader/


More information about the TYPO3-german mailing list