ruben: Sonderzeichen-Einfüge-Leiste

Hallo Forum!

Ich schreibe immer noch an meinem Vokabeltrainer und habe mit eurer Hilfe nun schon die größten Hürden bewältigt: es lebt!/funktioniert.
Nun will ich ein neues Feature implementieren und bin dabei auf einige Schwierigkeiten gestoßen:
Situation: User gibt Vokabel ein, aber kann leider nicht sämtliche Shortcuts für Sonderzeichen (in diesem Fall lebe der Mac hoch). Ich will dem Benutzer eine kleine Leiste an die Hand geben mit den für die jeweilig ausgewählte Sprache nötigen Sonderzeichen.
Ich habe bereits die Funktion implementiert, in der Sprachen und Sonderzeichen gemeinsam eingefügt werden können.
Das geht dann ungefähr so, dass ich in meiner User-Datenbank das Feld [Sprachen] und das Feld [Chars] habe mit korrespondierenden Zeilen.
Also z.B.

1 Französisch
2 Türkisch
3 Schwedisch

1 çïœ
2 çüö
3 åöä

(Diese Funktion ist in der stabilen Version nicht drin, aber auf http://voc.b.astahost.com/test.)

Soweit so gut. Nun zu meinen Problemen :-)
Ich lese die Sonderzeichen in einen Array ein, erstmal per Line und dann per Zeichen. Also (Beispiel ohne Einleserei, tut nichts zur Sache)
$chars = "åöä"
for($i=0;$i<strlen($chars;$i++) echo $chars[$i] . " ";
Dabei tritt mir das erste Problem auf die Füße: der Zeichensatz des Dokuments ist utf-8. Dementsprechend habe ich die Zeichen im Klartext in die Variable geschrieben und nicht irgendwie maskiert.
Die Ausgabe ist dann aber "? ? ? ? ?". Verwunderswert hierbei nicht nur, dass er die Zeichen nicht erkennt, sondern, dass er gleich 5 draus macht. Ich muss hierzu sagen, dass mir String=Array und alles recht neu war. Nunja.. Ich bin zuversichtlich, dass ihr mir sagen könnt, was ich hier falsch mache?!

Mein nächstes Problem ist folgendes:
Ich habe ja mehrere Sprachen und demzufolge mehrere Sonderzeichenkombinationen. Die grade einzugebene Sprache wählt man per Select-Menü aus. Nun müsste ich per Javascript die dazugehörigen Sonderzeichen in einer aktiv-anklickbaren Form ausgeben lassen.
Da stoße ich allerdings an meine Grenzen, da ich mit Javascript ja nicht beliebig den Inhalt ändern kann (oder dabei auf viele Kombatibilitätsprobleme stöße). Am liebsten wäre mir, wenn ich für jedes Zeichen einen eigenen Button hätte (da diese auch mit Hotkey bspw. Alt-y benutzt werden könnten). Zum Einfügen in die Textarea wollte ich die in einem der Feature-Artikel von selfHTML verfügbare insert(x,y)-Funktion benutzen.
Uppps! Da kommt mir beim Schreiben doch grad ne vernünftig klingende Idee: Buttons mit PHP schreiben und in divs für jeweilige sprache packen, nach Bedarf ein/-ausblenden. Spricht nichts gegen, oder?
Außer, dass die Accesskeys dann pro Sprache unique seien müssten, es sei denn ich ändere immer die Accesskeys im JS.. Ist aber viel Arbeit und die wenigsten werden es anwenden.. also lass ich die accesskeys aus. Sorry, gehöre zu den Menschen, denen die meisten Einfälle kommen, wenn sie behaupten sie hätten keine. Mein erstes Problem bleibt aber.

Vielen Dank, falls ihr euch erbarmt! Fühlt euch eingeladen, Probleme, die ihr mit der Seite habt anzumerken. Ich wollt sie erstmal für mich ans Laufen kriegen und dann kompatibler machen.
liebe Grüße,
Ruben

  1. echo $begrüßung;

    Ich lese die Sonderzeichen in einen Array ein, erstmal per Line und dann per Zeichen.
    $chars = "åöä"
    for($i=0;$i<strlen($chars;$i++) echo $chars[$i] . " ";
    Dabei tritt mir das erste Problem auf die Füße: der Zeichensatz des Dokuments ist utf-8. Dementsprechend habe ich die Zeichen im Klartext in die Variable geschrieben und nicht irgendwie maskiert.
    Die Ausgabe ist dann aber "? ? ? ? ?". Verwunderswert hierbei nicht nur, dass er die Zeichen nicht erkennt, sondern, dass er gleich 5 draus macht.

    Eigentlich müsste er 6 draus machen, da die angegebenen Zeichen in UTF-8 mit 6 Bytes kodiert werden. Und damit kommen wir zum Problem: PHP ist noch nicht Unicode/UTF-8-fähig. Das soll, meinen Erinnerungen zufolge, erst in Version 6 soweit sein.

    Es gibt einige Multibyte-Funktionen, zu denen ich nichts weiter sagen kann.

    Das Umwandeln in ISO-8859-1/15/sonstwas wird keine Lösung sein, da darin nicht alle UTF-8-Zeichen abgebildet werden können. Eventuell findest du aber einen ISO-8859-Zeichensatz, der alle gewünschten Zeichen gleichzeitig enthält... Aber wenn du einen sprachunabhängigen Vokabeltrainer schreiben möchtest fällt das auch aus.

    for($i=0;$i<strlen($chars;$i++) echo $chars[$i] . " ";
    [...] String=Array [...]

    Das ist so nicht richtig. Die Syntax um auf einzelne Zeichen zuzugreifen ist: $string{$position}. Die Array-Klammern-Syntax [] sind nicht mehr aktuell.

    echo "$verabschiedung $name";

    1. Danke, hat mir weitergeholfen.
      Allerdings bin ich auf dem Gebiet eine Jungfrau... Ich will natürlich einen sprachenunabhängigen Vokabel-Trainer schreiben und dafür benötige ich ganz klar Unicode, soviel verstehe ich.
      Mir ist allerdings nicht ganz klar, was du meinst, wenn du sagst "PHP ist noch nicht Unicode-fähig". Denn ich kann Sonderzeichen aus einer Variable ja einfach so ausgeben (also echo "媩ºƒ";)
      Ich nehme an, dass die String-Funktionen noch nicht auf 6-Byte-Zeichen umgerüstet sind?
      Dann läge das Problem ja aber wahrscheinlich nur hier: Wenn ich versuche, den String anhand seiner Bytes zu zerschnippeln.
      Ich habe ja aber Einfluß auf die Einspeisung in die Datenbank. Wenn ich also meine Sonderzeichen als "å ö ä" verpacken würde und mit " " exploden, dann hätte ich ein simples Workaround, oder? Widerstrebt mir zwar etwas, weil es unnötiger Datenbankspeicher ist und außerdem wiederrum Action beim Ein und Ausgeben. Aber wenn mir niemand die richtige Multibyte-Funktion sagen kann (falls die überhaupt existiert, was ich nicht mit Sicherheit rausfinden kann).

      Danke für für den Hinweis, dass man auf jedes Zeichen in einem String von nun an mit {} zugreift statt mit []. (Ich formuliere das aus, weil ich bei meiner Suche nach den hier enthaltenen Worten nur auf einen alten Eintrag, der noch [] meinte, gestoßen bin.

      Grüße,
      Ruben

      1. echo $begrüßung;

        Mir ist allerdings nicht ganz klar, was du meinst, wenn du sagst "PHP ist noch nicht Unicode-fähig". Denn ich kann Sonderzeichen aus einer Variable ja einfach so ausgeben (also echo "媩ºƒ";)

        In diesem Falle reicht PHP die Bytes des Strings nur durch.

        Ich nehme an, dass die String-Funktionen noch nicht auf 6-Byte-Zeichen umgerüstet sind?

        UTF-8 verwendet 1 bis 4 Byte pro Zeichen.
        Die Stringfunktionen können solche Multibyte-Zeichen enthaltenen Zeichenketten nicht richtig verarbeiten. Sie sind nur für ein Byte pro Zeichen ausgelegt, bzw. sie gehen davon aus, dass jedes Zeichen nur ein Byte hat und jedes Byte ein Zeichen ist.
        Wenn Multibyte-Zeichen getrennt werden können sie natürlich nicht mehr richtig interpretiert werden, was dann zu ? führt.

        Dann läge das Problem ja aber wahrscheinlich nur hier: Wenn ich versuche, den String anhand seiner Bytes zu zerschnippeln.
        Ich habe ja aber Einfluß auf die Einspeisung in die Datenbank. Wenn ich also meine Sonderzeichen als "å ö ä" verpacken würde und mit " " exploden, dann hätte ich ein simples Workaround, oder?

        Ja. Alternativ könntest du dir ansehen, wie UTF-8-Zeichen kodiert sind und daran die "Zeichengrenzen" erkennen.

        Widerstrebt mir zwar etwas, weil es unnötiger Datenbankspeicher ist und außerdem wiederrum Action beim Ein und Ausgeben.

        Das explode() am Leerzeichen dürfte die einfachere Variante sein. Wenn dir das zu aufwändig erscheint, du diese Ergebnisse nicht immer wieder berechnen willst, kannst du auch den Einsatz von Sessions erwägen. Verlass dich dabei aber nicht auf dein Bauchgefühl, miss die Geschwindigkeitsunterschiede lieber nach.

        echo "$verabschiedung $name";

  2. Danke Multibyte-Funktion:
    $string = "ç€ä";
    for($i=0;$i<mb_strlen($string);$i++) {
     echo mb_substr($string, $i,1,'UTF-8') . " ";
     }
    Tut das was ich will.. Hoffe, dass das für ALLE Zeichen funktionieren wird, aber spricht ja eigentlich nichts gegen, oder?