scorbio: mal wieder EUROZeichen

Also erstmal ja ich habe gesucht!!!!
Jedoch sind leider alle Lösungsansätze irgendwie nicht möglich.

Habe das Problem des EURO-Zeichens beim FORM-Tag "INPUT" und "TEXTAREA".

Folgendes habe ich bereits gemacht:

  • Der Server ist auf UTF-8 kodiert.
  • Der Header der Seite ebenso.
  • Die Forms besitzen accept-charset="utf-8"
  • Innerhalb der PHP-Dateien ist die Codierung richtig.

Vorgehensweise
1. Eingabe Frontent  ==> € funktioniert.
2. Form wird über Ajax abgeschickt.

  
//Umwandeln der Zeichen im Form  
Xpert.AjaxLoad.Loader.prototype.getValue = function(elm)  
{  
 var value = (typeof elm === "object")? elm.value : elm;  
 return encodeURIComponent(value);  
}  
//Wegschicken an PHP  
Xpert.AjaxLoad.Loader.prototype.loadDOMAssistant = function(file, data)  
{  
 LoadDisplay("block");  
 var url = file;  
 if(data)  
 {  
  url = url + "?" + encodeURI(data);  
  DOMAssistant.AJAX.post(url, returnHandler);  
 }  
 else  
 {  
  DOMAssistant.AJAX.get(url, returnHandler);  
 }  
};  

3. Umwandeln des €-Zeichens von URI auf UTF8

  
foreach ($_REQUEST as $key => &$value )  
{  
 if (is_string  ($value))  
 {  
  // Convert the Euro symbol  
  $value = str_replace('%E2%82%AC', '€', $value);  
  $value = rawurldecode($value);  
         $value = utf8_decode($value);  
 }  
}  

4. Speicherung Datenbank ==> € funktioniert

So jetzt der Umgekehrte Weg
1. Abruf der Daten
2. Umwandeln des € auf HTML-Entity

  
function confirmeentities($mixText)  
{  
 if(is_array($mixText) || is_object($mixText))  
 {  
  foreach($mixText as $key => &$value)  
  {  
   $value = confirmeentities($value);  
  }  
 }  
 else  
 {  
  $mixText = str_replace('€', '€', $mixText);  
 }  
 return $mixText;  
}  

3. Umwandeln bei FORM-Feldern mit
htmlentities($strText, ENT_QUOTES);
4. Darstellung des € im Frontend als Symbol ein Quardrat mit zwei 00 und ner 80 drin. Wenn ich dieses Zeichen wieder abgespeicht und wird es als € wiedererkannt und gespeichert.

Als HTML-entity kann ich es leider nicht ausgeben, da es ja um FORM-Felder handelt.

Also evlt. kann mir einer einen Tipp geben, wie ich dieses "piep"-Zeichen herbekomm

Gruß scorbio

PS: Ich habe es als HTML-Kategoriesiert, da es sich um die Darstellung im Browser handelt

  1. muss was korrigieren.

    das Umwandeln fürs Frontend passiert mit

    mit htmlspecialchars($strText, ENT_QUOTES,"UTF-8"); nicht mit htmlentities($strText, ENT_QUOTES);

  2. Moin!

    Folgendes habe ich bereits gemacht:

    • Der Server ist auf UTF-8 kodiert.
    • Der Header der Seite ebenso.
    • Die Forms besitzen accept-charset="utf-8"
    • Innerhalb der PHP-Dateien ist die Codierung richtig.

    Wenn du vollkommen UTF-8-verarbeitungsfähig bist, dann entfallen einige deiner Schritte - weil sie schlicht und ergreifend überflüssig sind, dir aber deine Texte kaputtmachen!

    1. Umwandeln des €-Zeichens von URI auf UTF8

    Diese Umwandlung mach PHP schon automatisch für dich, die mußt du nicht noch extra einbauen. Denn würdest du ein ganz normales Formular abschicken, würde der Browser selbständig das URI-Encoding mit den Daten durchführen - und bekanntermaßen macht PHP diese Transportsicherung ja auch selbständig rückgängig.

    Zweitens behandelst du das Eurozeichen aus irgendeinem Grund hier gesondert. Warum? Es ist ein UTF-8-Zeichen wie jedes andere Zeichen auch (also auch wie das Alphabet "A-Z", die Umlaute, etc.). Der Extraweg str_replace() für das Eurozeichen und rawurldecode() für den Rest ist überflüssig.

    Drittens wolltest du ja intern alle Strings als UTF-8 behandeln. Warum konvertierst du dann den String mit utf8_decode() in ISO-8859-1? In diesem Encoding gibt es kein Eurozeichen! Eventuell nur durch die Sonderbehandlung vorher wird etwas, das in dem gewählten Encoding kein Eurozeichen ist, unter besonderen Umständen evtl. von deinen Sonderfunktionen doch für eines gehalten. Es ist aber schwachsinnig, irgendeine Krücke mit ISO-8859-1 aufzubauen, wenn man die ganze Kiste viel einfacher haben könnte, wenn man durchgehens UTF-8 benutzen könnte.

    foreach ($_REQUEST as $key => &$value )
    {
    if (is_string  ($value))
    {
      // Convert the Euro symbol
      $value = str_replace('%E2%82%AC', '€', $value);
      $value = rawurldecode($value);
             $value = utf8_decode($value);
    }
    }

      
    
    > 4. Speicherung Datenbank ==> € funktioniert  
      
    Wenn du auf Schritt 3 verzichten und in Schritt 4 der Datenbank sagen würdest, a) dass die zu speichernden Strings in UTF-8 abzulegen sind (Kollation), und b) dass die Datenkommunikation mit der DB auch in UTF-8 funktioniert (Query "SET NAMES utf8"), würde dieser Schritt wirklich verläßlich funktionieren.  
      
    
    > So jetzt der Umgekehrte Weg  
    > 1. Abruf der Daten  
    > 2. Umwandeln des € auf HTML-Entity  
      
    Wenn du in der DB UTF-8-Daten stehen hast, kannst du auf die Umwandlung in Entities komplett verzichten und brauchst nur das Escaping für die HTML-Zeichen <, > und & durchzuführen mit htmlspecialchars().  
      
    Dein zweiter Fehler ist, dass du die falsche numerische Zeichenreferenz benutzt. Das Eurozeichen ist in der Unicode-Zeichentabelle nicht an Position 128, sondern an Position 8364.  
      
    
    > ~~~php
      
    
    > function confirmeentities($mixText)  
    > {  
    >  if(is_array($mixText) || is_object($mixText))  
    >  {  
    >   foreach($mixText as $key => &$value)  
    >   {  
    >    $value = confirmeentities($value);  
    >   }  
    >  }  
    >  else  
    >  {  
    >   $mixText = str_replace('€', '&#0128;', $mixText);  
    >  }  
    >  return $mixText;  
    > }  
    > 
    
    
    1. Umwandeln bei FORM-Feldern mit
      htmlentities($strText, ENT_QUOTES);

    Diese Umwandlung erfolgt mit der falschen Funktion, und sie muß immer erfolgen, solange du nicht definiert hast, dass in der Datenbank HTML-Quelltext drinsteht (d.h. eventuell dort gespeicherte HTML-Tags wirksam werden sollen als Formatierung).

    1. Darstellung des € im Frontend als Symbol ein Quardrat mit zwei 00 und ner 80 drin. Wenn ich dieses Zeichen wieder abgespeicht und wird es als € wiedererkannt und gespeichert.

    Dieser seltsame Zirkelschluß kommt daher, dass das Encoding Windows-1252 das Eurozeichen an Position 128 definiert hat. Da Windows-1252 ansonsten aber nahezu identisch mit ISO-8859-1 ist, wird irgendeine Komponente (sei es Browser oder Editor) vermutlich mal eine automatische Erkennung durchführen und das verhunzte Unicode-Euro in ein korrektes Windows-1252-Euro umwandeln.

    Als HTML-entity kann ich es leider nicht ausgeben, da es ja um FORM-Felder handelt.

    Doch, das würde dir auch helfen - aber nur sehr am Rande. Alle Attributwerte von HTML-Feldern erlauben den Einsatz von Entities, "&euro;" im value würde korrekt als Eurozeichen wiedergegeben werden. Aber da du in deiner Verarbeitungskette sowieso massive Fehler hast, die sich jetzt nur anhand des Eurozeichens zeigen, aber vermutlich noch in diversen anderen, bislang nicht beachteten Fällen zum Tragen kämen, solltest du deine seltsame Verarbeitungsweise lieber direkt auf 100% UTF-8 umstellen. Es macht dir später deutlich weniger Kopfschmerz.

    Also evlt. kann mir einer einen Tipp geben, wie ich dieses "piep"-Zeichen herbekomm

    Das Zeichen "BEL" trägt in vielen Encodings die Codenummer 8. Allerdings ist nicht gesagt, dass der Computer dann auch piept.

    - Sven Rautenberg

    --
    "Love your nation - respect the others."
    1. Hallo Sven,

      Das Zeichen "BEL" trägt in vielen Encodings die Codenummer 8.

      äh, nein, knapp daneben - das wäre ein Backspace. BEL hat seit ASCII den Code 7 (Ctrl-G).

      Allerdings ist nicht gesagt, dass der Computer dann auch piept.

      Richtig, das System könnte das Steuerzeichen ebensogut ignorieren oder als lustiges graphisches Symbol ausgeben.

      Ciao,
       Martin

      --
      Man sollte immer wissen was man sagt
       - aber auf keinen Fall alles sagen, was man weiß.
      1. Moin!

        Das Zeichen "BEL" trägt in vielen Encodings die Codenummer 8.

        äh, nein, knapp daneben - das wäre ein Backspace. BEL hat seit ASCII den Code 7 (Ctrl-G).

        Ich hätte nachgucken können - aber da ich das Zeichen eigentlich seit der Programmiererei mit Turbo Pascal 4 vor gefühlt fünfzehn Jahren nicht mehr benötigt habe, sei mir dieser Lapsus verziehen. :)

        Allerdings ist nicht gesagt, dass der Computer dann auch piept.

        Richtig, das System könnte das Steuerzeichen ebensogut ignorieren oder als lustiges graphisches Symbol ausgeben.

        Beliebt sind z.B. Smilies aus dem IBM-Zeichensatz. :)

        - Sven Rautenberg

        --
        "Love your nation - respect the others."
    2. Danke euch beiden für die Nachricht.

      Das Problem ist es inzwischen ein riesige Anwendung.

      Die Problematik ist mir durch ausbewusst, dass es zu viele Codierungen sind. Problem ist es so zu machen wie du es sagst. Würde mich glaub ich x Tage brauchen aber so viel Zeit wird mir mein Chef nimmer dafür geben.

      Der Neue Stand der Dinge ist jetzt

      Der Punkt 3 wird nicht mehr mit
      htmlentities($strText, ENT_QUOTES); sondern mit
      htmlspecialchars($strText, ENT_QUOTES, "UTF-8"); gemacht. So funktioniert es auch mit der direkten Wiedergabe. Nur noch die Kodierung für eine Ajax-Rückgabe klappt noch nicht. Werd ich aber a schaffen.

      1. Moin!

        Danke euch beiden für die Nachricht.

        Das Problem ist es inzwischen ein riesige Anwendung.

        Dann ist es um so wichtiger, dass du diesen Anfangsfehler schnellstmöglich korrigierst - ansonsten fällt dir das Problem immer und immer wieder vor die Füße, und du wirst immer mehr Code einfügen müssen, um die ganzen Sonderfälle abzufangen - bis du am Ende vor lauter Sonderfallbehandlung gar nicht mehr verstehst, was da eigentlich abläuft.

        Je eher du korrektes UTF-8-Handling integrierst, desto besser.

        Die Problematik ist mir durch ausbewusst, dass es zu viele Codierungen sind. Problem ist es so zu machen wie du es sagst. Würde mich glaub ich x Tage brauchen aber so viel Zeit wird mir mein Chef nimmer dafür geben.

        Dann wird es das Beste sein, wenn du mit ihm darüber sprichst.

        Ist natürlich immer blöd, wenn man als derjenige, der es eigentlich wissen sollte, zugeben muß, schon direkt am Anfang einen Fehler gemacht zu haben - aber da gibts gewiß auch politisch vorteilhaftere Formulierungen. Wenn du die Gesamtumstellung in das Europroblem verpackst, sähe das vielleicht so aus: "Chef, ich weiß jetzt, warum das Eurozeichen nicht klappt. Dahinter steckt ein grundsätzliches Problem, dass ich vermutlich in drei Tagen beseitigt haben werde - danach werden wir nie wieder Probleme mit dem Encoding haben. Ok?"

        Der Punkt 3 wird nicht mehr mit
        htmlentities($strText, ENT_QUOTES); sondern mit
        htmlspecialchars($strText, ENT_QUOTES, "UTF-8"); gemacht. So funktioniert es auch mit der direkten Wiedergabe. Nur noch die Kodierung für eine Ajax-Rückgabe klappt noch nicht. Werd ich aber a schaffen.

        Denk dran: Ajax bzw. das XMLHttpRequest-Objekt in Javascript arbeitet ausschließlich mit UTF-8. Du kannst noch soviel versuchen - alle anderen Encodings werden nie funktionieren.

        Auch mit Entities wirst du potentiell auf Probleme stoßen, da das Funktionieren von Entities sehr vom Kontext abhängt, in dem sie betrachtet werden. XML beispielsweise kennt außer den Zeichen, die in XML Sonderbedeutung haben, keinerlei benannte Zeichen, also auch kein &auml; oder &euro;. Sowas gibts nur in HTML bzw. XHTML - oder dort, wo man dem XML per DTD o.ä. die Entities beigebracht hat.

        - Sven Rautenberg

        --
        "Love your nation - respect the others."
        1. Danke für den Tipp. naja selbst geschrieben hab ich diese Klasse nicht. Bin nur der jenige der es ausbaden darf. ;-)

          also ich stimme dir voll und ganz zu das dies immer wieder auftreten wird. Werde es so schnell wie möglich ändern. Jedoch erstmal in nem anderen Projekt damit gleich damit anfangen.

  3. Hi,

    $mixText = str_replace('€', '&#0128;', $mixText);

    Mal ganz abgesehen davon, daß in HTML-Dateien Zeichen mit Codes von 128 einschl. bis 159 einschl. nicht erlaubt sind:
    Wie kommst Du darauf, daß das Unicode-Zeichen 128 (Hex: 80) irgendetwas mit dem Eurozeichen zu tun haben könnte?

    Das Eurozeichen hat den Code Hex 20AC, Dez 8364.

    cu,
    Andreas

    --
    Warum nennt sich Andreas hier MudGuard?
    O o ostern ...
    Fachfragen unaufgefordert per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
    1. also das &#0128; ist die Tasteneingabe ALT+0128 = €, habe ich aus Typolight, inzwischen habe ich es jetzt auf &#8364;

      Danke für die Antwort habe das Problem gestern gelöst,
      es klappt alles wunderbar. danke für die Antworten.

      1. @@scorbio:

        also das &#0128; ist die Tasteneingabe ALT+0128 = €

        Nein. Zum Nachlesen:

        „Es ist ein häufiger Fehler, wenn Autoren in Windows-1252-codierten Texten das Euro-Zeichen als &#x80; [oder &#0128;] notieren. Zwar liegt das Euro-Zeichen in der Windows-1252-Codepage auf Position 80 (hexadezimal) [128 (dezimal)]; aber &#x80; sollte ein Steuerzeichen ergeben, denn das Escape wird aufgelöst zu dem Zeichen auf Position 80 (hexadezimal) im Unicode-Repertoire. (Allerdings korrigieren manche Browser diesen Fehler stillschweigend. […])“ [QA-ESCAPES]

        Live long and prosper,
        Gunnar

        --
        Erwebsregel 208: Manchmal ist das einzige, was gefährlicher als eine Frage ist, eine Antwort.