Probleme bei MySQL-Servern mit seltsamen Zeichensätzen

Gesperrt
Stefan_Br
Beiträge: 36
Registriert: Di 29. Nov 2005, 18:06
Kontaktdaten:

Probleme bei MySQL-Servern mit seltsamen Zeichensätzen

Beitrag von Stefan_Br » Mo 20. Feb 2006, 20:49

Beim Experimentieren mit verschiedenen Servern bin ich auf Folgendes gestoßen:

Manche MySQL-Server sind so eingestellt, dass sie nicht wie meistens in latin1 o.ä. mit PHP reden, sondern zum Beispiel in Unicode.

Dies lässt sich zwar grundsätzlich über die Konfiguration des Servers einstellen, auf die hat man aber oft keinen Zugriff. Das Ergebnis sind seltsame Zeichen in Contenido und Fehlfunktionen, z.B. werden der Modulcode und Artikeltitel nach Sonderzeichen abgeschnitten etc.

Man kann die Standardeinstellung des Servers aber beim Zugriff überschreiben. Ich poste mal ein paar Änderungen an der db_mysql.inc im Ordner conlib, die den Server dazu bringen alles umzukodieren, sodass Contenido damit umgehen kann und keiner weiteren Änderungen bedarf:

Unterhalb von

Code: Alles auswählen

class DB_Sql {
  
  /* public: connection parameters */
  var $Host     = "";
  var $Database = "";
  var $User     = "";
  var $Password = "";
dieses

Code: Alles auswählen

  var $charset  = 'latin1';
einfügen!

Außerdem unterhalb von

Code: Alles auswählen

  /* public: connection management */
  function connect($Database = "", $Host = "", $User = "", $Password = "", $charset = "") {

    /* Handle defaults */
    if ("" == $Database)
      $Database = $this->Database;
    if ("" == $Host)
      $Host     = $this->Host;
    if ("" == $User)
      $User     = $this->User;
    if ("" == $Password)
      $Password = $this->Password;
dieses

Code: Alles auswählen

    if ("" == $charset)
      $charset = $this->charset;
einfügen.
Nur ein kleines Stück weiter unterhalb von

Code: Alles auswählen

    /* establish connection, select database */
    if ( 0 == $this->Link_ID || !is_resource($this->Link_ID)) {

      $this->Link_ID=@mysql_connect($Host, $User, $Password);
      if (!$this->Link_ID) {
        $this->halt("connect($Host, $User, \$Password) failed.");
        return 0;
      }
dies

Code: Alles auswählen

      mysql_query('SET CHARACTER SET '.$this->charset, $this->Link_ID);
einfügen!

Siehe auch
http://dev.mysql.com/doc/refman/5.0/en/ ... ction.html
http://de2.php.net/manual/en/function.m ... coding.php


Das war es. Natürlich könnte man auch testen, ob das, was der DB-Server zurückliefert, Unicode ist und das dann entsprechend mit PHP konvertieren; dies hätte aber den Nachteil, dass es wahrscheinlich nicht so zentral zu implementieren wäre; außerdem sind die Konvertierungsfunktionen von PHP dürftig und letztlich würde man dann ja doch nicht damit arbeiten. Ich weiß außerdem nicht, ob es überhaupt möglich wäre, wenn der Server auf abstrusere fremdländische Zeichensätze gestellt wäre.

Könnte man doch eigentlich in die nächste Contenido-Version übernehmen, oder?
Zuletzt geändert von Stefan_Br am Di 13. Nov 2007, 21:31, insgesamt 1-mal geändert.

mvf
Beiträge: 1758
Registriert: Mo 1. Aug 2005, 00:35
Wohnort: in der schönen Hallertau, mitten im Hopfen
Kontaktdaten:

Beitrag von mvf » Mo 20. Feb 2006, 20:53

man verzeihe mir meine unwissenheit :?

kann es da nicht probleme mit z.b. arabisch oder kyrillisch geben? meine schon gelesen zu haben das member hier contenido in den babylonischsten sprachen einsetzen oder würfel ich da was durcheinander?
Grüsse, Guido

"A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools."
Mostly Harmless - Douglas Adams

Stefan_Br
Beiträge: 36
Registriert: Di 29. Nov 2005, 18:06
Kontaktdaten:

Beitrag von Stefan_Br » Di 21. Feb 2006, 20:22

Ähm, also soweit ich weiß, kann PHP gar nicht richtig Unicode, es kodiert Unicode bloß in ASCII-Strings und dann kann es irgendwie damit beschränkt umgehen.

In jedem Fall muss es aber wissen, womit es zu tun hat bzw. der Programmierer muss wissen, ob ein String nun Unicode oder was anderes enthält. Contenido ist offensichtlich so programmiert, dass es "normale" Strings vom DB-Server erwartet, bekommt es dann mit einem Mal etwas anderes geht gar nichts mehr, z.B. lässt sich dann die Ansicht zum Artikeleditieren nicht mehr aufrufen und es kommt eine eval 'd code Fehlermeldung, der auszuführende String habe Syntaxfehler. Das liegt daran, dass er aus der Datenbank gelesen wird; kommt er von dort als Unicode, eval() glaubt aber, er wär "normal" und interpretiert ihn entsprechend geht das natürlich nicht.

Wenn nun irgendwer Contenido auf kyrillisch etc. #benutzt#, muss er dies wohl mit einer Einstellung tun, bei der PHP und DB-Server "normal" reden, sonst ginge das ja gar nicht.
Wenn Du Dir mal den Code ansiehst, siehst Du auch, wie das funktioniert: Wenn man nämlich irgendwas, was nicht Programmcode ist, mit Contenido abspeichert, wird das Ganze vorher mit entsprechenden Funktionen (base64_encode, htmlentities oder so) in einen "normalen" String gepackt, der dann in der Datenbank abgespeichert wird und nach dem Auslesen wieder zurückgewandelt wird. Insofern kann Contenido ja mit Unicode umgehen und sorgt sogar dafür, dass es potenziell auch mit einer nicht Unicode-tauglichen Datenbank arbeiten könnte, es kann nur (durch die PHP-Beschränkungen) nicht einfach so herausfinden, was ein String ist, sondern muss es wissen. Und da ist es eben so angelegt, dass es immer glaubt, es rede mit dem DB-Server "normal".
Der DB-Server kann aber auch nicht so einfach wissen, was PHP bzw. Contenido erwarten, also redet er so, wie es in seiner Konfigurationsdatei steht. Dort steht in der Regel was "Normales", sodass alles klappt. Ist dies aber nicht der Fall, klappt gar nichts.
Um sich solch ein Missverständnis zu ersparen, sagt Contenido dem DB-Server nach obiger Code-Änderung explizit, dass es in latin1 reden will. Darauf stellt sich dann der DB-Server ein, egal, was in seiner Konfiguration steht, und alles sollte unabhängig von der Server-Voreinstellung klappen.

----------------------------------------------------------
Obige Änderungen wirken sich übrigens automatisch auch auf das Setup aus (nicht auf die DB-Tests) -> man sollte sie vor der Installation vornehmen, weil sonst bei der Installation teilweise kaputter Code in der DB landet. Hat man es falsch installiert (nach der Installation oder dem Umzug treten die entsprechenden Symptome auf), sollte man nach den Änderungen das Setup noch einmal im Upgrade-Modus laufen lassen, das korrigierte bei mir den kaputten Code in der Datenbank.
Die Inhalte brauchen bei einem Umzug in der Regel nicht konvertiert zu werden, weil sie ja nicht vom Setup, sondern vom Nutzer geschrieben wurden. Hat man zum Übernehmen der Inhalte z.B. phpMyAdmin in einer halbwegs aktuellen Version genommen, hat dies automatisch alles richtig gemacht, weil dies diese ganze Problematik offenbar von sich aus beherrscht.

-----------------------------------------------------------
So, ich hoffe, ich habe jetzt hier nichts grundlegend Falsches gepostet; es passt jedenfalls zu dem, was man im Web liest und meine Versuche ergeben haben; außerdem erscheint es mir recht logisch.

HerrB
Beiträge: 6935
Registriert: Do 22. Mai 2003, 12:44
Wohnort: Berlin
Kontaktdaten:

Beitrag von HerrB » Di 15. Aug 2006, 19:02

Verschoben.

Gruß
HerrB
Bitte keine unaufgeforderten PMs oder E-Mails -> use da Forum!

Newsletter: V4.4.x | V4.6.0-15 (Module, Backend) | V4.6.22+
Standardartikelliste: V4.4.x | V4.6.x
http://www.contenido.org/forum/search.php | http://faq.contenido.org | http://www.communido.net

yui
Beiträge: 140
Registriert: Di 17. Jun 2003, 17:55
Kontaktdaten:

Re: Probleme bei MySQL-Servern mit seltsamen Zeichensätzen

Beitrag von yui » Mo 18. Jan 2010, 17:00

Hallo Stefan,

Dein Beitrag hat mir bei meinem Sonderzeichenproblem bei domaindiscount24 geholfen.

Danke! und schön Grüsse
yui
Ich weiß, dass ich nichts weiß. Sokrates

Gesperrt