Wieder Umlaute und PHP

VoinG

Angesehenes Mitglied
Hallo!

Das Thema ist hier schon besprochen worden, ich habe viel gesucht, doch leider keine Lösung gefunden und selbst weiss ich auch nicht weiter:(

Folgendes Problem, sehr einfach:
Ich bekomme in einem Formular CODE $wert=$_REQUEST['Eingabe'];


Dann extrahiere ich immer ein Zeichen und versuche das durch Bilder zu ersetzen - nix schwieriges eigentlich. So funktioniert das bei mir:
CODE $laenge=strlen($wert);
for ($a=0; $a<$laenge; $a++)
{
$zeichen=substr($wert, $a, 1);

if ($zeichen=="0")
{
$bild.="<img src='0.gif'>";
}

if ($zeichen=="1")
{
$bild.="<img src='1.gif'>";
}
usw....
}


Läuft sehr gut.

Aber, wenn mein String ein Umlaut enthält, bekomme ich dann immer 252 bei ü und entsprechende Zahlen bei den anderen Umlauten. Ich habe vieles ausprobiert, aber nichts hilft. Z.B.

CODE if ($zeichen=="ü" || $zeichen=="Ü" || $zeichen=="ü" || $zeichen=="Ü" || $zeichen=="ü" || $zeichen=="%26%23252%3B").......
}


Hilft mir bitte, es geht nicht weiter, kann nicht weitermachen bis ich das Problem nicht gelöst habe...
sad.gif


Danke!
 
Der Zeichensatz kann nicht anders sein da ich mittels
CODE <form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" method="get">

das ganze an sich selbst schicke.

Obwohl ich habe nun eine komische Sache festegstellt - wenn ich auch meine Zeichenkette ausgebe sind die Umlaute da!
Also, bei
CODE echo"$wert";
wird normal z.B. 123aaäüö ausgegeben... Und wenn ich dann mit
CODE $zeichen=substr($wert, $a, 1);
(wie oben im Code) Text durch die Bilder ersetze, dann 2 Möglichkeiten:
1. Wenn
CODE charset=windows-1251
dann bekomme ich 123aa228252246
2. Wenn
CODE charset=UTF-8
dann überhaupt ohne Umlaute, 123aa!

Wie kann das sein?

Obwohl nein, im Quellcode steht dann bei windows-1251 nicht 123aaäüö sondern 123aa& #228;& #252;& #246;

Und bei utf-8 stehen wirklich Umlaute da!

Ich muss dann wohl die Frage anders stellen, warum funktioniert das hier nicht:

CODE
$laenge=strlen($wert);
for ($a=0; $a<$laenge; $a++)
{
$zeichen=substr($wert, $a, 1);
if ($zeichen=="ü" || $zeichen=="Ü")
{
$bild.="<img src='UE.gif'>";
}
}
 
QUOTE (VoinG @ Mi 14.2.2007, 12:41) Ich muss dann wohl die Frage anders stellen, warum funktioniert das hier nicht:

CODE
$laenge=strlen($wert);
for ($a=0; $a<$laenge; $a++)
{
$zeichen=substr($wert, $a, 1);
if ($zeichen=="ü" || $zeichen=="Ü")
{
$bild.="<img src='UE.gif'>";
}
}


Mit Umlauten müsstest du eigentlich den iso-8859-1 Zeichensatz verwenden. UTF-8 und windows-1251 (wie kommst du auf das windows-1251 Charset?) kennen keine Umlaute, daher werden logischerweise auch keine (korrekt) dargestellt.

Zu deinem Code:
Du arbeitest dich Zeichenweise durch. Umlaute werden aber eigentlich mit insgesammt 5 Zeichen vom System interpretiert.
 
QUOTE (wie kommst du auf das windows-1251 Charset?)

Wegen dem Russischen
wink.gif
windows-1251 ist das einzige was manschmal wirklich hilft, aber ich bin bereit das zu opfern
smile.gif


Zu meinem Problem, ich hab jetzt vieles ausprobiert und bin total ratlos...Wie meinst du das
QUOTE mit insgesamt 5 Zeichen vom System interpretiert.
, wenn ich im Seitenquelltext nur ein Zeichen - ü sehe und keine &uu...;

Ich habe "htmlentities" gefunden, die hilft aber irgendwie nicht, da bekomme ich ganz komische Ergebnisse.

Noch schlimmer, ich führe Tests durch, um einige php-Fuktionen zu prüfen. Ich habe zufällig entdeckt, dass wenn ich z.B. eine Variable $wert="aouäöü" habe und dann versuche durch substr() usw. rauszufinden wieviele Umlaute ich habe, wird zwischen a und ä, o und ö, u und ü nicht unterschieden, ich bekomme also 6 als Ergebnis!

Ich habe wirklich keine Ahnung wie weiter..


Ok, ich habe noch etwas gefunden, funktioniert aber nicht. Könnte mir vielleicht jemand erklären warum?


CODE <?php
$auml=chr(228);
echo $auml; //hier bekomme ich ganz ordentlich 'ä'!
$count=substr_count("äxxxx", $auml);
echo $count; //und hier ganz nicht ordentlich '0', obwohl 'ä' vorhanden ist
?>


und noch


CODE <?php
$string="a";
if(eregi("[üöä]",$string))
echo "drin";
else echo "nicht drin"; //bekomme ich drin! weil zwischen ä und a nicht unterschieden wird!
?>
 
Der Webserver generiert und verarbeitet einen Datenstrom mit einer bestimmten Codierung. Wenn dann nur in

QUOTE <meta http-equiv="content-type" content="text/html; charset=utf-8" />


ein anderer Zeichensatz eingesetzt wird, dann paßt der behauptete Zeichensatz nicht zum tatsächlichen Zeichensatz (bzw. jeder Browser zeigt das anders an). Das hat aber nichts mit den hiesigen Problemen zu tun (verschlimmert sie womöglich).


QUOTE Aber, wenn mein String ein Umlaut enthält, bekomme ich dann immer 252 bei ü und entsprechende Zahlen bei den anderen Umlauten


Offenbar (ich verwende PHP nicht, kann deshalb nur spekulieren) betrachtet PHP den Wert von $zeichen als 1-Byte-Datenstrom und übersetzt nur die ersten 128 Codepunkte (also ASCII [EDIT]) korrekt und gibt für die anderen die Ascii-Codes aus (bzw. interpretiert den Eintrag direkt als Ganzzahl). Also ist doch die Lösung simpel: Auf = 252 überprüfen und dann 'ü' ausgeben.


QUOTE UTF-8 und windows-1251 (wie kommst du auf das windows-1251 Charset?) kennen keine Umlaute


UTF-8 kennt natürlich Umlaute. Das Problem hier ist ja, daß die Daten gerade nicht (wie in der Microsoft-Welt seit Jahren üblich) konsistent als UTF-8 bzw. UTF-16 interpretiert werden (damit steht auch in einer 1-Zeichen-Variable ein Zeichen, das in UTF-8 mit mehreren Bytes codiert wird), sondern daß das 'ü' als "252" oder 252 (String oder Integer) zurückgegeben wird.


QUOTE Noch schlimmer, ich führe Tests durch, um einige php-Fuktionen zu prüfen. Ich habe zufällig entdeckt, dass wenn ich z.B. eine Variable $wert="aouäöü" habe und dann versuche durch substr() usw. rauszufinden wieviele Umlaute ich habe, wird zwischen a und ä, o und ö, u und ü nicht unterschieden, ich bekomme also 6 als Ergebnis!


Das (und das RegEx drunter) hängt (zumindest in NET) mit der Sortierung zusammen: Binär, Berücksichtigung von Groß/Klein, Akzent - und dann gibt es noch 'German_Phonebook' versus Latin1_General, die sich darin unterscheiden, ob ä nach z oder als ae interpretiert wird. Ein kleines Beispiel:


QUOTE 1> select charindex('ä' Collate Latin1_General_BIN,'aei'), charindex('ä' Collate
Latin1_General_CI_AI, 'aei')
2> go

----------- -----------
0 1

Latin1_General_CI_AI behandelt ä wie a, General_Bin nicht. Das hat aber nichts mit dem obigen Zurückgeben von 'ü' als 252 zu tun.

Edit: Statt '128 Byte' muß es natürlich 128 Codepunkte bzw. 7 Bit heißen. Mit den ersten 7 Bit lassen sich 128 verschiedene Zeichen codieren.
 
Natürlich hast du Recht, mit QUOTE Datenstrom mit einer bestimmten Codierung. Wenn dann nur in

<meta http-equiv="content-type" content="text/html; charset=utf-8" />
ein anderer Zeichensatz eingesetzt wird, dann paßt der behauptete Zeichensatz nicht zum tatsächlichen Zeichensatz (bzw. jeder Browser zeigt das anders an)
aber z.B.
QUOTE Auf = 252 überprüfen und dann 'ü' ausgeben.
geht nicht, ich erkläre jetzt warum.

Ich bin mir fast sicher, ich weiss wo mein Problem liegt. Durch Testen habe ich herausgefunden, dass die meisten PHP-Fuktionen die doch funktionieren sollten, mit "meinen" Umlauten nicht funktionieren! Und dann habe ich das gefunden:

CODE $umlaute = array("ä", "ö", "ü");
$keineuml = array("ae", "oe", "ue");
und hier 2 Möglichkeiten
1. Möglichkeit:
$newwert = str_replace($vokale, $keineuml, "abcdäöü"); //also einfach eingetipptes String
echo "$newwert"; ////funktioniert alles richtig, ich bekomme abcdaeoeue !!

2. Möglichkeit:
$newwert = str_replace($vokale, $keineuml, $wert);
////$wert ist das, was PHP bekommt, ($wert=$_REQUEST['Eingabe'];)
echo "$newwert"; ////funktioniert nicht richtig, ich bekomme abcdäöü!!!!!




Das bedeutet also, dass PHP irgendwas mit meinem Formular macht, irgendwas mit dem Zeichensatz vielleich in diesem Formular!

Es kann doch nicht sein dass keiner hier mit den Umlauten in Formularen nicht konfrontiert wurde..
Wie soll ich das Problem lösen?
Danke!

PS. Noch ein Beweis:

CODE
$spwert=htmlspecialchars("äää");

funktioniert


CODE $spwert=htmlspecialchars($wert);
funktioniert nicht! Hilfe, ich habe kaputte unsichtbare Umlaute!
blink.gif
 
Überprüfe doch erstmal welche Kodierung deine PHP Datei hat. Schaut so aus, als wäre es eine Multibyte Kodierung wie zB. UTF8... für den Fall kannst du einen Großteil der Standard-PHP-Stringfunktionen nicht nutzen. Stattdessen solltest du die Funktionen der mb_string lib verwenden:
http://de.php.net/manual/de/ref.mbstring.php

Die Kodierung der PHP Datei findest du raus, indem du in deinem Editor in den Dateieinstellungen nachschaust. Ich meine damit also nicht die Meta-Angaben...
 
Ja, Maik, vielen Dank, ich hab's heute um kurt vor 4 Uhr morgens entdeckt
smile.gif
3 Tage habe ich dafür gebraucht
blink.gif
Windows Notepad war die richtige Lösung für mich, nur so hab ich's geschafft, meine php-Datei als utf-8 zu speichern
biggrin.gif


Nun kann ich z.B. mein String auf Umlaute überprüfen z.B.
CODE $umlaute = array("ä", "ö", "ü", "ß", "Ä", "Ö", "Ü");
$keineuml = array("aumlaut", "oumlaut", "uumlaut","eszet","aumlaut", "oumlaut", "uumlaut");
$wert = str_replace($umlaute, $keineuml, $wert);
smile.gif


Damit ist das größte Problem vom Fenster.

Ich habe aber noch ein Punkt wo ich keine Lösung finde...

CODE $laenge=strlen($wert);
for ($a=0; $a<$laenge; $a++)
{
$zeichen=substr($wert, $a, 1);
if ($zeichen=="a" || $zeichen=="A")
{
$bild.="<img src='A.gif'>";
}//funtioniert!

if ($zeichen=="ü" || $zeichen=="Ü")
{
$bild.="<img src='UE.gif'>";
}//funktioniert doch nicht!


Warum kann ich mit den Umlauten nicht vergleichen? Gibt es eine passende Funktion statt '==' ?
Danke!
 
Vielen Dank für die Hilfe, aber ich denke ich werde langsam abergläubisch...
Mein PHP kennt die beiden Fuktionen nicht... QUOTE Fatal error: Call to undefined function...

Auf php.net sehe ich
QUOTE mb_substr
(PHP 4 >= 4.0.6, PHP 5)
, mein phpinfo() gibt
QUOTE PHP Version 4.4.4

4.4.4 ist doch größer als 4.06, oder?
blink.gif
Ich werde total verrückt mit dem Code... Soll ich meinen Hoster anschreiben?

Danke!
 
Ich habe heute meinen Hoster angeschrieben, aber ich glaube nicht so sehr dass es hilft, sie waren immer stützig in diesen Fragen.
Was ich komisch finde, ich hab's geschaft bei dem Hoster auf PHP Version 5.1.5 umzustellen und das funktioniert trotzdem nicht.
Local habe ich PHP Version 5.0.5, hab selbst nichts gemacht, verändert oder hinzugefügt und das funktioniert doch!

Bis ich die Antwort vom Hoster nicht erhalten habe, fällt jemandem vielleicht sonst etwas ein?
Vielen Dank für eure Hilfe!
 
Hier ist es keine Frage der PHP-Version, sondern der eingebundenen/kompilierten Erweiterungen. Und das Multibyte-Zeug ist (leider) in den offiziellen Zend-Releases nicht per default drin. Bei den DotDeb-Versionen wiederum schon, und soweit ich mich erinnere auch in den ganzen xamp-releases.

Ob Multibyite aktiviert ist, erkennst du in der phpinfo() unter "mbstring".
 
Tja, ich hab überhaupt kein mb_string in meinem phpinfo... Aber das ist mir schon klar, diese Möglichkeit bekomme ich nicht.
Aber es kann doch nicht wahr sein, dass ich in einem String die Umlaute nicht auffangen kann?
Das sollte doch anders funktionieren, oder? Sagt mir, was mache ich falsch?

Andere Frage, warum bekomme ich hier CODE echo ord('ä'); echo ord('ü'); echo ord('ö');
3 Mal 195?

Und warum bei diesem Code
CODE $zeichen=substr($wert, $a, 1);
if (ord($zeichen)==195)
{
$bild.="<img src='AE.gif'>";
}
funktioniert das mit allen 4 Umlauten?

Letzte Frage - wo bekomme ich eine gültige ASCII Tabelle, wo auch Umlaute drin stehen? http://www.asciitable.com/ scheint nicht vollständig oder nicht richtig zu sein. Und hilft mir das überhaupt weiter, mit ascii-Werten zu vergleichen?

Danke für die Hilfe!
PS. Ich hab so ein Gefühl dass ich irgendwas Wichtiges nicht kenne oder nicht verstehe.. Ich kann im Netz absolut nichts finden, aber das kann doch nicht wahr sein dass ich der Erste bin der nach Umlauten in einem String sucht...
 
QUOTE (VoinG @ Fr 16.2.2007, 18:52)Andere Frage, warum bekomme ich hier
CODE echo ord('ä'); echo ord('ü'); echo ord('ö');
3 Mal 195?


Wenn Du die Datei als UTF-8 speicherst, dann werden äöü wahrscheinlich zwei Byte belegen, ord liest das erste Byte - und das ist dann immer gleich 195 als Ganzzahl (PS: Ich nutze kein PHP/Perl, insofern Spekulation).


QUOTE (VoinG @ Fr 16.2.2007, 18:52)Letzte Frage - wo bekomme ich eine gültige ASCII Tabelle, wo auch Umlaute drin stehen? http://www.asciitable.com/ scheint nicht vollständig oder nicht richtig zu sein. Und hilft mir das überhaupt weiter, mit ascii-Werten zu vergleichen?


Die Frage ist unsinnig. ASCII ist gleich dem Unicode-Block Basic Latin, der nächste Unicode-Block (bis Codepunkt 255) umfaßt die deutschen Umlaute und ist gleich dem ISO-8859-1, die www.asciitable.com scheint dagegen irgendeine der alten DOS- oder Windowscodierungen für den Bereich 128-255 auszugeben.


QUOTE (VoinG @ Fr 16.2.2007, 18:52)Ich hab so ein Gefühl dass ich irgendwas Wichtiges nicht kenne oder nicht verstehe.. Ich kann im Netz absolut nichts finden, aber das kann doch nicht wahr sein dass ich der Erste bin der nach Umlauten in einem String sucht...


Du wirfst einfach noch viel zu viel durcheinander. Im Prinzip kannst Du, wenn die Datei als UTF-8 codiert ist, die deutschen Umlaute als Zwei-Byte-Zeichen betrachten und mußt nur von diesen beiden Bytes den Integer-Wert wissen: 195 ist der erste, also nimm oben so etwas wie Substring ( zweites Zeichen) und ermittele davon die Ordinalzahl. Effizient ist das natürlich nicht. Lektüre: Unicode statt ASCII

Die Standard-PHP-Funktionen scheinen Strings als 1-Byte-Zeichensätze zu betrachten - und sind damit natürlich mit deutschen Umlauten überfordert. Aber da Du oben 252 für 'ü' bekommst (da war die Datei wohl noch nicht als UTF-8 gespeichert), entspricht das dem Latin-1-Supplement-Block bzw. der 8-Bit-Codierung ISO-8859-1, also kannst Du doch damit die deutschen Umlaute bewältigen. Da mußt Du nur ein Zeichen prüfen.
 
QUOTE ...aber da Du oben 252 für 'ü' bekommst (da war die Datei wohl noch nicht als UTF-8 gespeichert), entspricht das dem Latin-1-Supplement-Block bzw. der 8-Bit-Codierung ISO-8859-1, also kannst Du doch damit die deutschen Umlaute bewältigen. Da mußt Du nur ein Zeichen prüfen.

Boooah, wie geil dass du das bemerkt hast!!! Jetzt funktioniert das, ich bin so dankbar! Ich zeige noch den Code, sollte das jemand später gebrauchen:
CODE $laenge=strlen($wert);


for ($a=0; $a<$laenge; $a++)
{
$zeichen=substr($wert, $a, 1);

//Umlaut Überprüfung!
if (ord($zeichen)==228 || ord($zeichen)==196)
{
$bild.="<img src='AE.gif'>";
}

if (ord($zeichen)==246 || ord($zeichen)==214)
{
$bild.="<img src='OE.gif'>";
}

if (ord($zeichen)==252 || ord($zeichen)==220)
{
$bild.="<img src='UE.gif'>";
}

//Umlaut Überprüfung Ende

//usw...
if ($zeichen=="0")
{
$bild.="<img src='0.gif'>";
}

//......
if ($zeichen=="a" || $zeichen=="A")
{
$bild.="<img src='A.gif'>";
}
}


Vielen Dank! Deine anderen Links werde auf jeden Fall später studieren, aber erst schlafen
wink.gif

4 Tage habe ich dafür gebrauch, das war aber keine verlorene Zeit, ich hab richtig viel gelernt.
PS. Jeder aus diesem Thread hat ein Recht auf ein (zwei, drei...) Kölsch von mir
biggrin.gif
, sobald man Köln besucht!

Nochmals Danke an alle!
 
Ich würde das etwas effizienter machen. Verwende zwar kein PHP, aber so als Pseudocode:

CODE for ($a=0; $a<$laenge; $a++)
{
$zeichen=upper(substr($wert, $a, 1)); // nur Großbuchstaben
$i = ord($zeichen); // einmal Ordinalwert holen

case $i // irgendetwas wird es sicherlich in dieser Form geben

220 : $v = "UE";
196 : $v = "AE";
214 : $v = "OE";

48 TO 57, 65 TO 90: $v = $zeichen;
end

$bild.= "<img src='".$v.".gif'>";
}


Sprich: Oben einmal sofort das Zeichen als Großbuchstaben holen und einmal als Integer in $i hinterlegen, dann nicht wiederholt per if, sondern in einer einmaligen Case-(oder wie das in PHP heißt)-Schleife prüfen: Die Umlaute werden direkt geprüft, die Zahlen 0-9 entsprechen den Codepunkten 48-57, 65 bis 90 sind die Großbuchstaben. Dann am Schluß einmalig zusammensetzen.
 
nicht gerade eine tolle vorgehensweise... zumal du mit ca. 100 verschiedenen Zeichen immer diese Umlaute driffst. Wenn man es wenigstens annähernd richtig machen will, sollte man prüfen ob das vorherige Zeichen auf ein Multibyte Zeichen hindeutet... Also immer prüfen, vergleichen mit 195 bzw. 0xC3
 
Zurück
Oben