Tommi: UTF-8: was muss man beachten?

Moin,

was muss man beachten, damit eine Seite bzw. ein Skript UTF-8-tauglich ist?

So weit bin ich bis jetzt:

  • der Code muss in einem Editor geschrieben werden, der UTF-8 kann
  • es muss ein Header mit dem UTF-8-Zeichensatz gesendet werden (z.B. mit PHP: header('Content-Type: text/html; charset='utf-8');
  • auch im HTML-Head muss der Zeichensatz angegeben werden (<meta http-equiv="content-type" content="text/html; charset=utf-8" />)

Ist das alles? Und: kann mir jemand einen UTF-8-tauglichen Editor für Windows nennen (ich verwende bisher Phase 5, der kann's leider nicht)?

Danke!
Tommi

  1. Ich hatte das Problem neulich auch, und fast gescheitert bin ich daran, daß der Server, auf dem das alles laufen sollte, ein ISO-8859-1 kodiertes Filesystem verwendet. Dadurch werden alle Dateianfragen unglaublich kompliziert, da urlencode() in UTF-8 anders arbeitet als in ISO.

    Ich habe dann mein eigenes kleines Encodierungsprogramm für Dateinamen geschrieben, das überhauptkeine Sonderzeichen verwendet. Das klappt gut.

    Und du mußt natürlich bei allen Functionen, die Zeichen erzeugen, die Kodierung angeben,, also z.B. bei htmlentities().

    Bezog sich jetzt alles auf PHP

    Grüße

    Heizer

    1. Hallo Heizer,

      danke für Deine Antwort!

      Ich hatte das Problem neulich auch, und fast gescheitert bin ich daran, daß der Server, auf dem das alles laufen sollte, ein ISO-8859-1 kodiertes Filesystem verwendet. Dadurch werden alle Dateianfragen unglaublich kompliziert, da urlencode() in UTF-8 anders arbeitet als in ISO.

      Oh ja, daran hab ich noch gar nicht gedacht!

      Und du mußt natürlich bei allen Functionen, die Zeichen erzeugen, die Kodierung angeben,, also z.B. bei htmlentities().

      OK, also so, oder?
      $string = htmlentities($string, ENT_COMPAT, 'UTF-8');

      Tommi

      1. Oh ja, daran hab ich noch gar nicht gedacht!

        Ich auch nicht, bis ich dann mein wunderbar funktionierendes CMS auf meinen Server  hochgeladen hatte. Bei mir lokal funktioniert alles mit UTF-8, was immer wieder zu Fragezeichen oder Kästchen in Systemmeldungen führt.

        UTF-8 ist eine wunderbare Idee, und gelobt sei jeder, der es verwendet, aber man muß sich auf den ein oder anderen Sallstrick einstellen.

        $string = htmlentities($string, ENT_COMPAT, 'UTF-8');

        Exakt, und das funktioniert auch. Allerdings gibt es in PHP keine wirklich native UTF-8 Unterstützung. Idealerweise würde ini_set("default_charset","UTF-8") nicht nur einen entsprechenden Header senden (was ich in meiner sowieso vorhandenen .htaccess mache), sondern auch alle Funktionen mit dem entsprechenden charset arbeiten lassen.

        Funktionen die meines Wissens überhaupt nicht sinnvoll mit UTF-8 arbeiten sind chr() und ord(). Wenn du also denkts, du könntest mit diesen hinter einige Fehlerursachen blicken, vergiß es.

        Ich möchte hier noch die Funktion posten, die ich verwende, um unabhängig von der codierung des filesystems Sonderzeichen in Dateinamen verwenden zu können:

        function myurlencode($mix) {
         if (is_string($mix)) {
          foreach ($GLOBALS["specialChars"] as $key => $elem) {
           $mix = str_replace($key,str_repeat("q",strlen($elem)).$elem,$mix);
          }
          return $mix;
         }
         elseif (is_array($mix)) {
          foreach ($mix as $key => $elem) {
           $out[myencode($key)] = myencode($elem);
          }
          return $out;
         }
         else
          return $mix;
        }

        $GLOBALS["specialChars"] ist dabei ein Array, das die Ersetzungspaare in UTF-8 enthält, als z.B. array("ä" => "ae","ö" => "oe") etc. Um diese von normalen Vorkommnissen der Buchstabenkombination unterscheiden zu können, werden so viele "q"'s vorangestellt, wie die Kodierung lang ist, also z.B. qqae oder qqoe.

        Ich bin mit dieser Lösung nicht wirklich zufrieden, aber sie funktioniert für den Moment, und mit deutschen Sonderzeichen. Die komplette Bandbreite von UTF-8 bekommt man damit allerdings nur mit einiger Arbeit an den Erstetzungspaaren.

        Um die Schnittstelle zum Filesystem flexiebel zu halten, lasse ich alle entsprechenden Funktionen über eine eigene Funktion aufrufen, so kann ich an einem zentralen Punkt alle Fehler beheben.

        function fs() {
         if ($GLOBALS["disable"]["filesystem"] === TRUE)
          return true;
         $vars = func_get_args();
         $func = array_shift($vars);
         $negate = FALSE;
         if ($func{0} == "!") {
          $func = str_replace("!","",$func);
          $negate = TRUE;
         }
         $vars = myencode($vars);
         $ret = call_user_func_array($func,$vars);
         $ret = mydecode($ret);
         if ($ret == TRUE and $negate == TRUE)
          $ret = FALSE;
         elseif ($ret == FALSE and $negate == TRUE)
          $ret = TRUE;
         return $ret;
        }

        Die Verwendung ist einfach:
        Statt         fopen("fileName.csv")
        schreibt man  fs("fopen","fileName.csv")

        Mit $GLOBALS["disable"]["filesystem"] lassen sich die Funktionen auch sperren und TRUE zurückgeben. Dies ist nicht bei allen Funtionen sinnvoll, hat sich aber beim Testen von Dateilöschungen oder Verschieben als sehr nützlich erwiesen, da man dann die Datei nicht jedesmal neu anlegen muß, wenn das löschen funktioniert, aber andere Teile der Seite noch nicht.

        Hoffe, ich hab dir ein bißchen auf dem Weg zum universellen Zeichensatz helfen können, gib nicht auf!

        Grüße

        Heizer

  2. Moin,

    Nabend!

    was muss man beachten, damit eine Seite bzw. ein Skript UTF-8-tauglich ist?

    Die Seite in UTF-8 verfassen:

    • der Code muss in einem Editor geschrieben werden, der UTF-8 kann

    und UTF-8 sollte dann auch als Zeichensatz eingestellt sein (beim Speichern).

    • es muss ein Header mit dem UTF-8-Zeichensatz gesendet werden (z.B. mit PHP: header('Content-Type: text/html; charset='utf-8');

    gute Idee

    • auch im HTML-Head muss der Zeichensatz angegeben werden (<meta http-equiv="content-type" content="text/html; charset=utf-8" />)

    nein, oder (statt auch). Meine Erfahrung ist, dass du im Allgemeinen, wenn du nen HTTP-Header sendest, die HTML meta-Angabe nicht mehr brauchst (eine Ausnahme: bei XHTML sollte man im Header "Content-Type: text/html" angeben und in HTML "<meta http-equiv="Content-Type" content="application/xhtml+xml" />", weil sonst der IE nicht will.)

    Danke!
    Tommi

    Keine Ursache, sagt Robert

      • auch im HTML-Head muss der Zeichensatz angegeben werden (<meta http-equiv="content-type" content="text/html; charset=utf-8" />)

      nein, oder (statt auch). Meine Erfahrung ist, dass du im Allgemeinen, wenn du nen HTTP-Header sendest, die HTML meta-Angabe nicht mehr brauchst

      Der HTTP-Header ist relevant, wenn das Dokument per HTTP übertragen wird. Die Kodierungsangabe im meta-Element ist in allen anderen Fällen wichtig. Diese Angaben haben andere Wirkungen und nützen anderen Zwecken, sodass man nicht davon sprechen kann, dass eines davon das andere überflüssig macht.

      (eine Ausnahme: bei XHTML sollte man im Header "Content-Type: text/html" angeben und in HTML "<meta http-equiv="Content-Type" content="application/xhtml+xml" />", weil sonst der IE nicht will.)

      Wie kommst du darauf? Natürlich muss XHTML als text/html ausgeliefert werden, wenn MSIE mitspielen soll. Wieso sollte man dann aber einen abweichenden Medientyp im meta-Element angeben?

      Mathias

      1. [...]

        Der HTTP-Header ist relevant, wenn das Dokument per HTTP übertragen wird. Die Kodierungsangabe im meta-Element ist in allen anderen Fällen wichtig. Diese Angaben haben andere Wirkungen und nützen anderen Zwecken, sodass man nicht davon sprechen kann, dass eines davon das andere überflüssig macht.

        Naja, für lokale Dateien stimmt das schon, aber das entscheidende Atrribut lautet http-equiv, da steckt ja schon HTTP mit drin.

        (eine Ausnahme: bei XHTML sollte man im Header "Content-Type: text/html" angeben und in HTML "<meta http-equiv="Content-Type" content="application/xhtml+xml" />", weil sonst der IE nicht will.)

        Wie kommst du darauf?

        Ich habs ausprobiert. Der korrekte (empfohlene, weil noch nicht als Standard) MIME-Type für XHTML ist nun mal application/xhtml+xml und nicht text/html. Bei text/xml stellt der IE übrigens das XML-Gerüst dar, auch nicht schlecht.

        Mathias

        Gruß, Robert

        1. (eine Ausnahme: bei XHTML sollte man im Header "Content-Type: text/html" angeben und in HTML "<meta http-equiv="Content-Type" content="application/xhtml+xml" />", weil sonst der IE nicht will.)

          Wie kommst du darauf?

          Ich habs ausprobiert. Der korrekte (empfohlene, weil noch nicht als Standard) MIME-Type für XHTML ist nun mal application/xhtml+xml und nicht text/html. Bei text/xml stellt der IE übrigens das XML-Gerüst dar, auch nicht schlecht.

          Wenn du die XHTML-Datei als text/html auslieferst (Content-Type-Header in der HTTP-Kommunikation), ist der MIME-Typ des Dokuments eben text/html. Es ist unsinnig, im meta-Element eine anderslautende Angabe zu machen, diese wird sowieso ignoriert, sie hat keine Wirksamkeit (bei der charset-Angabe darin ist es etwas anderes). Die HTML-Browser erwarten an dieser Stelle logischerweise text/html.
          Das Ausliefern von XHTML 1.0 als text/html ist durch die XHTML-Spezifikation vorgesehen, sofern die Kompatibilitätsrichtlinien eingehalten werden. Es ist also ein »korrekter« MIME-Typ. Außerdem ist application/xhtml+xml durchaus entgegen deiner Aussage standardisiert. Er ist aber (korrekt im Content-Type-Header) nicht empfohlen, weil nur wenige Browser wirklich damit umgehen können.

          Mathias

          1. Wenn du die XHTML-Datei als text/html auslieferst (Content-Type-Header in der HTTP-Kommunikation), ist der MIME-Typ des Dokuments eben text/html. Es ist unsinnig, im meta-Element eine anderslautende Angabe zu machen, diese wird sowieso ignoriert, sie hat keine Wirksamkeit (bei der charset-Angabe darin ist es etwas anderes).

            Meinst du damit, dass Mozilla, Opera, Safari, ... dann an der XML-Deklaration und am DOCTYPE erkennen, dass es sich um XHTML handelt?

            Die HTML-Browser erwarten an dieser Stelle logischerweise text/html.

            Klar, ich rede ja auch von "XHTML-Browsern" ;-)

            Das Ausliefern von XHTML 1.0 als text/html ist durch die XHTML-Spezifikation vorgesehen, sofern die Kompatibilitätsrichtlinien eingehalten werden.

            Aha, das wusste ich gar nicht, ich kenne nur die Empfehlung von application/xhtml+xml bzw. text/html für ältere Browser (wie den IE).

            Es ist also ein »korrekter« MIME-Typ.

            Natürlich ist text/html ein korrekter MIME-Typ, schon seit sehr langer Zeit.

            Außerdem ist application/xhtml+xml durchaus entgegen deiner Aussage standardisiert.

            Das wusste ich noch gar nicht, als ich vor einiger Zeit (vor bestimmt über nem Jahr) in der XHTML-Spec nachgeschaut habe, stand, dass es noch nicht genormt sei (da gibt es wohl nen RFC oder sowas, wo alle "bekannten" MIME-Typen drin stehen).

            Er ist aber (korrekt im Content-Type-Header) nicht empfohlen, weil nur wenige Browser wirklich damit umgehen können.

            Du meinst wahrscheinlich vom Marktanteil her wenige Browser. Mir fällt nur der IE ein, bei lynx könnte ich mir vorstellen, dass der sogar mittlerweile XHTML-fähig ist.

            Mathias

            Gruß, Robert

            1. Wenn du die XHTML-Datei als text/html auslieferst (Content-Type-Header in der HTTP-Kommunikation), ist der MIME-Typ des Dokuments eben text/html. Es ist unsinnig, im meta-Element eine anderslautende Angabe zu machen, diese wird sowieso ignoriert, sie hat keine Wirksamkeit (bei der charset-Angabe darin ist es etwas anderes).

              Meinst du damit, dass Mozilla, Opera, Safari, ... dann an der XML-Deklaration und am DOCTYPE erkennen, dass es sich um XHTML handelt?

              Nein?! Sie verarbeiten das Dokument als echtes X(HT)ML, wenn es im Content-Type-Header als application/xml, text/xml oder appliation/xhtml+xml ausgewiesen ist.
              Wenn es hingegen als text/html deklariert wird, wird das Dokument mit einem allgemeinen Parser verarbeitet, der sich nicht speziell an XML-Regeln hält. Viele Unterschiede zwischen HTML und (»echtem«) XHTML kommen in diesem Fall gar nicht zum tragen (z.B. ist Wohlgeformtheit unwichtig).

              Das Ausliefern von XHTML 1.0 als text/html ist durch die XHTML-Spezifikation vorgesehen, sofern die Kompatibilitätsrichtlinien eingehalten werden.

              Aha, das wusste ich gar nicht, ich kenne nur die Empfehlung von application/xhtml+xml bzw. text/html für ältere Browser (wie den IE).

              Davon rede ich ja. Zu diesem Zweck existieren die Kompatibilitätsrichlinien: Um allen alten Browsern, die XHTML nicht richtig unterstützen, das XHTML als HTML (text/html) vorzusetzen, in der Hoffnung, dass sie etwas gescheites daraus machen.

              Es ist also ein »korrekter« MIME-Typ.

              Natürlich ist text/html ein korrekter MIME-Typ, schon seit sehr langer Zeit.

              Ich widersprach damit deiner Aussage »der korrekte MIME-Type für XHTML ist nun mal application/xhtml+xml und nicht text/html«.
              Natürlich ist text/html der für HTML vorgesehene MIME-Typ, aber er ist auch gemäß den Standards unter den genannten Umständen für XHTML vorgesehen.

              Außerdem ist application/xhtml+xml durchaus entgegen deiner Aussage standardisiert.

              Das wusste ich noch gar nicht, als ich vor einiger Zeit (vor bestimmt über nem Jahr) in der XHTML-Spec nachgeschaut habe, stand, dass es noch nicht genormt sei

              Das muss wohl über zwei Jahre her sein. http://www.w3.org/TR/xhtml1/#media

              (da gibt es wohl nen RFC oder sowas, wo alle "bekannten" MIME-Typen drin stehen).

              Jeder Medientyp hat sein eigenes RFC. So auch application/xhtml+xml.
              http://www.ietf.org/rfc/rfc3236.txt

              Er ist aber (korrekt im Content-Type-Header) nicht empfohlen, weil nur wenige Browser wirklich damit umgehen können.

              Du meinst wahrscheinlich vom Marktanteil her wenige Browser.

              Auch in den Browsern, denen man zuschreibt, sie könnten XHTML, gibt es einige Einschränkungen und Fallstricke, vor allem in geringfügig älteren Versionen. MSIE ist wahrlich nicht der einzige kritische Browser, auch ältere Geckos, Operas und KHTML-basierte Browser machen im Detail Probleme bei application/xhtml+xml, sodass man extrem vorsichtig sein sollte.

              Mathias