MySQL Suche und utf-8 Format
Marcel
- datenbank
Hallo!
Ich bin gerade dabei eine Seite mehrsprachig zu machen, deutsch, englisch und tschechisch.
Die dafür benötigten Texte werden in einer MySQL Datenbank im utf-8 Format abgelegt. Es galt schon diese Hürde zu nehmen. Aber das funktioniert nun perfekt.
Jetzt muss ich allerdings noch eine Suchfunktion programmieren und dabei werden die deutschen und englischen Begriffe sofort gefunden, die tschechischen aber nicht. Woran kann das liegen?
Meine Suchfunktion sieht für diesen Fall so aus:
opendb(...)
mysql_query("SET NAMES 'utf8'");
mysql_query("SET CHARACTER SET 'utf8'");
if (!$result = @mysql_db_query($dbname,"select de, cz from rs_lang where cz like '$cz_txt'")) {$err=mysql_error(); return(3);}
while($row = mysql_fetch_array($result))
{...)
Wie schon gesagt, in tschechisch wird überhaupt nichts gefunden. Deutsch und englisch funktioniert.
Hat jemand einen Tipp für mich?
Vielen Dank + Gruß
Marcel
echo $begrüßung;
mysql_query("SET NAMES 'utf8'");
mysql_query("SET CHARACTER SET 'utf8'");
Was macht das SET CHARACTER SET da? SET NAMES sollte ausreichen.
Hat jemand einen Tipp für mich?
Ich habe mit Pinyin und LIKE unter phpMyAdmin keine Probleme. Tritt das Problem auch auf, wenn du das Statement mit phpMyAdmin absetzt? Wenn ja, erstelle doch mal bitte den kleinstmöglichen Datenhaufen (eine Tabelle, ein Feld, einen Datensatz), um das Problem nachzuvollziehen (mit phpMyAdmin exportieren inklusive Tabellenstruktur).
echo "$verabschiedung $name";
Hallo!
Ich habe mit Pinyin und LIKE unter phpMyAdmin keine Probleme. Tritt das Problem auch auf, wenn du das Statement mit phpMyAdmin absetzt? Wenn ja, erstelle doch mal bitte den kleinstmöglichen Datenhaufen (eine Tabelle, ein Feld, einen Datensatz), um das Problem nachzuvollziehen (mit phpMyAdmin exportieren inklusive Tabellenstruktur).
Wenn ich die select Anweisung nach phpMyAdmin kopiere dann klappt die Suche:
select de, cz from rs_lang where cz like 'Vše'
Aber halt nur im phpMyAdmin.
Hier trotzdem mal einen Auszug aus der Tabelle:
CREATE TABLE rs\_lang
(
id
int(11) NOT NULL auto_increment,
variable
varchar(20) collate latin1_general_ci default NULL,
seite
varchar(20) collate latin1_general_ci NOT NULL default '',
bemerkung
varchar(50) collate latin1_general_ci NOT NULL default '',
de
text collate latin1_general_ci NOT NULL,
eng
text collate latin1_general_ci,
cz
text character set utf8 collate utf8_czech_ci,
PRIMARY KEY (id
)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=199 ;
rs\_lang
rs\_lang
(id
, variable
, seite
, bemerkung
, de
, eng
, cz
) VALUES (21, 'sp_sortieren_nach', 'menu', '', 'Sortieren nach', 'classifying by', 'Třídit podle');rs\_lang
(id
, variable
, seite
, bemerkung
, de
, eng
, cz
) VALUES (22, 'sp_angemeldet_als', 'menu', '', 'Angemeldet als', 'Logged in as\r\n', 'Nahlásit jako');rs\_lang
(id
, variable
, seite
, bemerkung
, de
, eng
, cz
) VALUES (23, 'sp_kunde', 'menu', '', 'Kunde', 'Customer', 'Zákazník');rs\_lang
(id
, variable
, seite
, bemerkung
, de
, eng
, cz
) VALUES (25, 'sp_passw', 'menu', '', 'Passw:', 'Passw:', 'Heslo:');rs\_lang
(id
, variable
, seite
, bemerkung
, de
, eng
, cz
) VALUES (26, 'sp_kontakt', 'kontakt', '', 'Kontakt', 'Contact', 'Kontakt');rs\_lang
(id
, variable
, seite
, bemerkung
, de
, eng
, cz
) VALUES (28, 'sp_firma', 'kontakt', '', 'Firma', 'Company', 'Firma');echo $begrüßung;
Wenn ich die select Anweisung nach phpMyAdmin kopiere dann klappt die Suche:
select de, cz from rs_lang where cz like 'Vše'
Aber halt nur im phpMyAdmin.
Dann vermute ich einen Fehler in der Scriptverarbeitung oder Clientkommunikation. Ist das Script UTF-8 kodiert? Stimmt die charset-Angabe im Content-Type-Meta-Element? Sendet der Server einen gleichnamigen HTTP-Header?[1][2] Ist für das Formular irgendeine charset-Angabe vorhanden?[3] Wie sieht die Byte-Folge aus, die du an die Datenbank sendest?[4] Werden sonst irgendwelche zeichenkodierungsrelevanten Dinge verwendet?[5]
[1] Firefox mit livehttpheaders-extension eignet sich, um dies zu überprüfen.
[2] Dieser hat Vorrang vor der Meta-Angabe.
[3] Ist nicht unbedingt nötig, aber falls doch ...
[4] echo chunk_split(bin2hex($sql), 2, ' ');
[5] Extensions mbstring, iconv, recode oder dergleichen
echo "$verabschiedung $name";
Hallo!
Dann vermute ich einen Fehler in der Scriptverarbeitung oder Clientkommunikation. Ist das Script UTF-8 kodiert? Stimmt die charset-Angabe im Content-Type-Meta-Element?
Das könnte ein kritischer Punkt sein. Ich versuche mal den Aufbau zu erklären:
Die Seite A, wo die Suche gestartet wird, ist utf8 kodiert und mit der richtigen Charset Angabe.
Nach dem Absenden von A wird auf Seite B verzweigt. Das ist eine reine Script-Seite wo die Suche formatiert wird und ein Function aus einer library aufgerufen wird.
Die Seite B ist utf8 kodiert und mit "header('Content-type: text/html; charset=utf-8');" formatiert.
Von dieser Seite verzweige ich mit einem "header('Location: http://'.getenv('HTT..." nach erfolgreichem Aufruf der Function entweder wieder auf Seite A oder im Falle eines Fehlers auf Seite C wo die Fehlermeldung ausgegben wird. Und wegen dem header('Location... darf auf Seite B keinerlei html Ausgabe erfolgen.
Kann darin die Ursache des Problems liegen?
Sendet der Server einen gleichnamigen HTTP-Header?[1][2] Ist für das Formular irgendeine charset-Angabe vorhanden?[3] Wie sieht die Byte-Folge aus, die du an die Datenbank sendest?[4] Werden sonst irgendwelche zeichenkodierungsrelevanten Dinge verwendet?[5]
[1] Firefox mit livehttpheaders-extension eignet sich, um dies zu überprüfen.
Ich habe sie gesucht aber nicht gefunden, die "livehttpheaders-extension" für den Firefox. Kann mir vielleicht jemand sagen wo man diese bekommt?
[2] Dieser hat Vorrang vor der Meta-Angabe.
[3] Ist nicht unbedingt nötig, aber falls doch ...
[4] echo chunk_split(bin2hex($sql), 2, ' ');
Ich habe nach dem opendb() den query für die MySQL Abfrage an $sql übergeben. Und bekomme die folgende Ausgabe:
56 c5 a1 65
Mit den Hexadezimal Werten kann ich leider nicht so viel Anfangen. Wo kann ich da entsprechenden Infos bekommen?
Das werde ich mir dann gleich noch mal anschauen.
Auf jeden Fall schon einmal tausend Dank an Dich dedlfix für die Unterstützung!!!
Gruß Marcel
echo $begrüßung;
Das könnte ein kritischer Punkt sein. Ich versuche mal den Aufbau zu erklären:
Sieht etwas kompliziert aus, scheint aber nicht die Ursache zu sein, denn:
Ich habe nach dem opendb() den query für die MySQL Abfrage an $sql übergeben. Und bekomme die folgende Ausgabe:
56 c5 a1 65
Mit den Hexadezimal Werten kann ich leider nicht so viel Anfangen. Wo kann ich da entsprechenden Infos bekommen?
Für Werte kleiner als 128 (hex 80) kann man eine ASCII-Tabelle nehmen.
56 = V
65 = e
c5 a1 sieht sehr nach UTF-8 aus, und ergibt š (kleines s mit Caron/Hatschek)
ergibt also ein UTF-8-kodiertes Vše, so wie vorgesehen.
Das scheint also auch in Ordnung zu sein. Vielleicht hast du nur die Jokerzeichen % oder _ vergessen? Findet denn vielleicht ein LIKE '%Vše%' etwas? (Ist überhaupt ein 'Vše' enthalten? In deinen Beispieldatensätzen ist keins drin.)
Ich bin grad mit meinem Latein am Ende.
[5] Extensions mbstring, iconv, recode oder dergleichen
Das werde ich mir dann gleich noch mal anschauen.
Die sind dann interessant, wenn du Stringverarbeitung machst, wie Substrings bilden. PHP geht, solange es nicht Version 6 geworden ist, von einem Byte pro Zeichen aus. Zeichen mit mehreren Bytes werden dann nicht richtig verarbeitet und oft unbrauchbar.
[1] Firefox mit livehttpheaders-extension eignet sich, um dies zu überprüfen.
Ich habe sie gesucht aber nicht gefunden, die "livehttpheaders-extension" für den Firefox. Kann mir vielleicht jemand sagen wo man diese bekommt?
http://livehttpheaders.mozdev.org/ Findet man meines Wissens nach nicht in der offiziellen Extensions-Sammlung, aber übers große G :-)
echo "$verabschiedung $name";
echo $begrüßung;
Nachtrag:
c5 a1 sieht sehr nach UTF-8 aus, und ergibt š (kleines s mit Caron/Hatschek)
UTF-8-Codes findet man beispielsweise unter http://www.utf8-zeichentabelle.de/unicode-utf8-table.pl.
(Da sie Liste nach Unicode-Positionen geordnet ist, und man nicht nach der UTF-8-Kodierung suchen kann, könnte man, wenn man den UTF-8-Code nicht durch Blättern findet, gemäß den Umkodierungsregeln (siehe http://de.wikipedia.org/wiki/UTF-8) die Unicode-Positionsnummer ermitteln und dann danach die entsprechende Seite wählen.)
echo "$verabschiedung $name";