c--: Zeichencode in Zeichen konvertieren / Sonderzeichen in Form

Hallo,

ich habe wohl ein digitales Brett vorm Kopf und bitte um Hilfe...

Es geht um eine Webseite, die über POST (XMLHttpRequest/Ajax) den Inhalt einer textarea an ein PHP-Script schicken soll. Das PHP-Script soll dann damit weiterarbeiten, im Moment lasse ich mir damit die empfangenen Daten anzeigen - um zu sehen, was ankommt.
Die textarea kann alle möglichen Sonderzeichen enthalten - Anführungszeichen, Fragezeichen, Umlaute, auch asiatische Zeichen sollen funktionieren.

Als erstes habe ich dabei einfach mein JavaScript den value aus der textarea rausholen lassen, diesen mit escape() verschlüsselt (es darf ja kein & enthalten sein) und als einen (von mehreren) Parametern an die Funktion SendData (siehe unten) gegeben.
Dies habe ich mal in der Funktion SendText() vereinfacht nachgebaut.

Mein PHP-Script hat diesen Parameter mit $_Request['...'] entgegengenommen. Ein Entschlüsseln war nicht mehr nötig, da der String dann schon automatisch entschlüsselt war - ein Leerzeichen, das das JavaScript mit escape() in ein %20 verwandelt hatte, wird mit $_Request im PHP-Script gleich als Leerzeichen empfangen.
Das funktioniert auch mit Umlauten, nicht aber mit Anführungszeichen - diese werden von PHP seltsamerweise als " empfangen, also so, wie man sie in PHP escapen müsste ($str = """), obwohl der escape-Aufruf in JavaScript vor dem Senden der Daten eigentlich ein %22 daraus gemacht hat.
Beispiel:
In der textarea steht:
$main = "
JavaScript escaped daraus:
%24main%20%3D%20%22
Dies wird über SendData() ans PHP-Script geschickt, welches empfängt:
$main = "

Woher kommt der Backslash?

Also habe ich anders versucht, Daten bzw. Sonderzeichen von JavaScript zu PHP zu übertragen - ich habe in JavaScript eine Funktion (encode2) geschrieben, die jedes Zeichen mit seinem Zeichencode ausgibt, getrennt von einem Punkt. Dieser String wird dann vom PHP-Script decodiert (decode2).
Und dies funktioniert bei Umlauten nicht. Ein mb_ord("ä") gibt mir zwar 228 aus, aber ein mb_chr(228) oder ein mb_chr(mb_ord("ä")) gibt ä (2 Zeichen!) aus.
Offensichtlich funktioniert also die Funktion mb_chr() nicht zuverlässig.

Wie kann ich also zuverlässig in PHP einen Zeichencode in das entsprechende Zeichen konvertieren, sodass ich also aus 228 ein ä erhalte?

Ich bin für jeden Tipp dankbar.

Hier die angesprochenen Funktionen:

function SendText()  
{  
//Beispielcode  
var txt = document.getElementById('mytextarea').value;  
var dat = "par1=" + par1 + "&par2=" + par2 + "&txt=" + escape(txt);  
SendData("php.php", dat);  
}  
  
function SendData(url, params)  
{  
var http = new XMLHttpRequest();  
http.open("POST", url, true);  
  
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");  
http.setRequestHeader("Content-length", params.length);  
http.setRequestHeader("Connection", "close");  
  
http.onreadystatechange = function()  
{  
//Return code received  
if (http.readyState == 4 && http.status == 200)  
{  
//Success  
  
returncode = http.responseText;  
}  
  
http.send(params);  
}  

function encode2(input)  
{  
buf = "";  
for (i = 0; i < input.length; i++)  
{  
if (buf != "") buf = buf + ".";  
buf = buf + input.charCodeAt(i);  
}
function decode2($input)  
{  
$buf = "";  
$arr = explode(".", $input);  
for ($i = 0, $size = sizeof($arr); $i < $size; $i++)  
{  
if ($arr[$i] != "") $buf .= mb_chr($arr[$i]);  
}  
  
return $buf;  
}  
  
function mb_html_entity_decode($string)  
{  
    if (extension_loaded('mbstring') === true)  
    {  
        mb_language('Neutral');  
        mb_internal_encoding('UTF-8');  
        mb_detect_order(array('UTF-8', 'ISO-8859-15', 'ISO-8859-1', 'ASCII'));  
  
        return mb_convert_encoding($string, 'UTF-8', 'HTML-ENTITIES');  
    }  
  
    return html_entity_decode($string, ENT_COMPAT, 'UTF-8');  
}  
  
function mb_ord($string)  
{  
    if (extension_loaded('mbstring') === true)  
    {  
        mb_language('Neutral');  
        mb_internal_encoding('UTF-8');  
        mb_detect_order(array('UTF-8', 'ISO-8859-15', 'ISO-8859-1', 'ASCII'));  
  
        $result = unpack('N', mb_convert_encoding($string, 'UCS-4BE', 'UTF-8'));  
  
        if (is_array($result) === true)  
        {  
                return $result[1];  
        }  
    }  
  
    return ord($string);  
}  
  
function mb_chr($string)  
{  
    return mb_html_entity_decode('&#' . intval($string) . ';');  
}
  1. Hi,

    $main = "
    Woher kommt der Backslash?

    von einer schlechten Server-Konfiguration, die magic_quotes aktiviert hat. Informiere Dich über die Wege, dies zu umgehen.

    Und dies funktioniert bei Umlauten nicht. Ein mb_ord("ä") gibt mir zwar 228 aus, aber ein mb_chr(228) oder ein mb_chr(mb_ord("ä")) gibt ä (2 Zeichen!) aus.
    Offensichtlich funktioniert also die Funktion mb_chr() nicht zuverlässig.

    Zuverlässiger als Deine eigenen Codes: Sie spuckt ein UTF-kodiertes Ergebnis aus, während Du offenbar mit ISO arbeitest. Verwende *unbedingt* an *ausnahmslos* *jeder* Stelle *ausschließlich* UTF-Kodierung.

    Wie kann ich also zuverlässig in PHP einen Zeichencode in das entsprechende Zeichen konvertieren, sodass ich also aus 228 ein ä erhalte?

    Du hast ein perfektes UTF-"ä" erhalten. Nutze es weise.

    Cheatah

    --
    X-Self-Code: sh:( fo:} ch:~ rl:| br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
    1. $main = "
      Woher kommt der Backslash?

      von einer schlechten Server-Konfiguration, die magic_quotes aktiviert hat.

      Danke für den Tipp, auch an Sven Rautenberg!
      Habe es mit einem php_flag magic_quotes_gpc Off in der .htaccess (Root-Verzeichnis) deaktiviert.
      Ohne meinen Verschlüsselungsumweg (encode2()/decode2()), also vor dem Senden escape() und Empfangen über $_Request[], funktioniert es jetzt einwandfrei. Umlaute sind Umlaute und Anführungszeichen sind Anführungszeichen.
      Es interessiert mich aber nach wie vor, meinen (wenn auch überflüssigen) Verschlüsselungsumweg zum Laufen zu bringen.

      Offensichtlich funktioniert also die Funktion mb_chr() nicht zuverlässig.

      Zuverlässiger als Deine eigenen Codes: Sie spuckt ein UTF-kodiertes Ergebnis aus, während Du offenbar mit ISO arbeitest.

      Erst mal danke für das richtige Stichwort.
      Wenn ich genau das mache, wovon du mir so dringend abrätst, nämlich im PHP-Script den empfangenen String mit utf8_decode() ins ISO-Format umwandeln, dann bekomme ich alles, wie ich's mir vorstelle (ä ist ä). Dieser String wird dann unter anderem in eine Textdatei gespeichert, welche von einem anderen PHP-Script eingelesen wird und in einer Webseite (UTF-8) ausgegeben wird - erfolgreich.

      Verwende *unbedingt* an *ausnahmslos* *jeder* Stelle *ausschließlich* UTF-Kodierung.

      Darf ich - nachdem mein Beispiel eben auch nach dem Verwenden von utf8_decode() funktioniert - nach dem Warum fragen?

      Du hast ein perfektes UTF-"ä" erhalten.

      Das war mir anfangs nicht klar - soweit jetzt kein Problem.

      Nutze es weise.

      Mein Einsatz von utf8_decode ist ganz offensichtlich alles andere als weise.
      Aber darf ich nach dem Grund fragen?

      1. Moin!

        Verwende *unbedingt* an *ausnahmslos* *jeder* Stelle *ausschließlich* UTF-Kodierung.

        Darf ich - nachdem mein Beispiel eben auch nach dem Verwenden von utf8_decode() funktioniert - nach dem Warum fragen?

        Das Warum ist recht simpel zu erklären: Webseiten sind im Browser IMMER Unicode. Auch in Formularfelder kann der User immer alle definierten Unicode-Zeichen eingeben. Das will man eventuell nicht (beispielsweise für Usernamen oder Dateinamen), aber die Kontrolle über die Zeicheneingabe sollte man dann definiert in seinem eigenen Skript ausüben, und nicht die diversen "Oh, ich kann das Zeichen nicht übermitteln, was mach ich jetzt?"-Korrekturen der diversen Browser aktivieren.

        Denn die Browser verhalten sich in solchen Fällen sehr unterschiedlich.
        Manche schicken dir einfach UTF-8, obwohl du ISO-8859-1 erwartest. Das sieht nicht schön aus, aber mit viel Aufwand könnte man diese Zeichen hinterher wieder reparieren.

        Manche schicken dir echte ASCII-Fragezeichen "?" anstelle der nicht in ISO-8859-1 codierbaren Zeichen. Solche Fragezeichen erlauben keinerlei Reparatur.

        Manche Browser schicken dir anstelle des Unicode-Zeichens eine numerische Zeichenreferenz: &#1234; - sowas sieht ebenfalls nicht schön aus, vor allem: Wenn du beim Wiederausgeben des Textes das Zeichen wieder siehst, hast du in Wirklichkeit eine Sicherheitslücke. Das Zeichen ließe sich allerdings ebenfalls noch reparieren.

        Die Sache mit der Reparatur scheitert allerdings an dem Punkt, wo mehrere unterschiedliche Browser alle unterschiedlich kaputte Zeichen senden, und du hinterher eine Mischung diverser Zeichen reparieren müsstest, aber keine Indizien hast, welche Reparaturmethode denn korrekt wäre. Denn alle diese "kaputten" Zeichen könnten ja auch korrekt gewesen sein, weil der Benutzer die genau so schreiben wollte - beispielsweise, um in einem Forum über Codierprobleme zu diskutieren.

        Du hast ein perfektes UTF-"ä" erhalten.

        Das war mir anfangs nicht klar - soweit jetzt kein Problem.

        Nutze es weise.

        Mein Einsatz von utf8_decode ist ganz offensichtlich alles andere als weise.
        Aber darf ich nach dem Grund fragen?

        Du konvertierst aus dem Raum aller computerlesbarer Zeichen (irgendwas bei 200.000 Stück) in den nur in ISO-8859-1 definierten Zeichenraum (256 Zeichen). Das geht nicht ohne Verluste, und es fängt schon beim Euro-Zeichen an - denn das ist in ISO-8859-1 nicht definiert und geht dabei kaputt.

        Und der eventuelle Impuls, dann doch einfach das Eurozeichen durch &euro; zu ersetzen, bevor du dekodierst, ist auch die falsche Antwort: Mit UTF-8 musst du dir keine Gedanken machen, welche Zeichen eventuell kaputt gehen, weil einfach alle dargestellt werden können. Und das Entity-Mischmasch stört dich hinterher ganz extrem beim erneuten Anzeigen von Texten auf der Webseite, denn die müssen mit htmlspecialchars() behandelt werden, wenn sie "Text" sein sollen (und kein HTML).

        - Sven Rautenberg

      2. Hi,

        Verwende *unbedingt* an *ausnahmslos* *jeder* Stelle *ausschließlich* UTF-Kodierung.
        Darf ich - nachdem mein Beispiel eben auch nach dem Verwenden von utf8_decode() funktioniert - nach dem Warum fragen?

        ergänzend zu Svens Antwort: ISO-Kodierungen enthalten einen stark begrenzten Zeichensatz - deshalb gibt es so viele davon. UTF hingegen enthält *alle* Zeichen. Wenn wir Kontakt mit außerirdischen Lebensformen aufnehmen, werden deren Schriftzeichen (sofern sie ein solches Konzept kennen) in UTF übernommen werden. Im Grunde sind ISO-Kodierungen ein Kropf am offenen Bein, sie hätten nie erfunden werden sollen. Ein Fehler der Geschichte, der mittlerweile für permanente Probleme sorgt - beispielsweise das Deine.

        Cheatah

        --
        X-Self-Code: sh:( fo:} ch:~ rl:| br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
        X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
        X-Will-Answer-Email: No
        X-Please-Search-Archive-First: Absolutely Yes
        1. @@Cheatah:

          nuqneH

          UTF hingegen enthält *alle* Zeichen.

          Die Formulierung ist unglücklich. UTF ist kein Zeichensatz; es „enthält“ keine Zeichen.

          Besser: Mit UTF lassen sich alle Zeichen codieren.

          Aber wirklich alle? Wenn du die Außerirdischen mit einbeziehst: bei 2 hoch irgendwas ist Schluss. ;-)

          Qapla'

          --
          Gut sein ist edel. Andere lehren, gut zu sein, ist noch edler. Und einfacher.
          (Mark Twain)
  2. Moin!

    Die textarea kann alle möglichen Sonderzeichen enthalten - Anführungszeichen, Fragezeichen, Umlaute, auch asiatische Zeichen sollen funktionieren.

    Ajax arbeitet grundsätzlich mit UTF-8 - also ist der Zeichenvorrat kein Problem. Wenn PHP auf der anderen Seite damit klarkommt, und idealerweise auch alle normal ausgelieferten Seiten auf UTF-8 basieren, hat man keine Probleme mit unterschiedlichen Codierungen.

    Als erstes habe ich dabei einfach mein JavaScript den value aus der textarea rausholen lassen, diesen mit escape() verschlüsselt (es darf ja kein & enthalten sein) und als einen (von mehreren) Parametern an die Funktion SendData (siehe unten) gegeben.

    escape() ist die falsche Funktion. encodeURIComponent() ist richtig.

    Das funktioniert auch mit Umlauten, nicht aber mit Anführungszeichen - diese werden von PHP seltsamerweise als " empfangen, also so, wie man sie in PHP escapen müsste ($str = """), obwohl der escape-Aufruf in JavaScript vor dem Senden der Daten eigentlich ein %22 daraus gemacht hat.

    PHP hat Magic Quotes aktiviert. Solltest du ausschalten - und nur wenn das nicht geht, das Escapen wieder rückgängig machen. Dazu gibts vielfache Postings im hiesigen Archiv sowie überall im Web, wie man das macht - Google kennt die meisten Vorkommen.

    Und dies funktioniert bei Umlauten nicht. Ein mb_ord("ä") gibt mir zwar 228 aus, aber ein mb_chr(228) oder ein mb_chr(mb_ord("ä")) gibt ä (2 Zeichen!) aus.

    Offenbar ist die Seite, in der du UTF-8-codierte Zeichen ausgibst, nicht mit dieser Codierung an den Browser übertragen worden. Check mal, welches Encoding dir dein Browser in den Seiteninformationen anzeigt.

    Die Information über das korrekte Encoding kannst du mit PHP aber mit der Funktion header() anpassen.

    Deine geschriebenen Funktionen sind leider allesamt überflüssig. Wenn, dann würden sie an Symptomen herumdoktoren, die niemals auftreten würden, wenn du gewisse Anfängerfehler hinsichtlich des Encodings nicht machen würdest.

    Lies beispielsweise auch mal in unserem Wiki nach, was Encoding genau ist: http://wiki.selfhtml.org/wiki/Doku:Grundlagen/Zeichenkodierung_und_geschriebene_Sprache sowie http://wiki.selfhtml.org/wiki/Themen:Zeichencodierung.

    - Sven Rautenberg

    1. @Sven Rautenberg

      Vorausgesetzt, ich verwende *nicht* utf8_decode()...

      Als erstes habe ich dabei einfach mein JavaScript den value aus der textarea rausholen lassen, diesen mit escape() verschlüsselt (es darf ja kein & enthalten sein) und als einen (von mehreren) Parametern an die Funktion SendData (siehe unten) gegeben.

      escape() ist die falsche Funktion. encodeURIComponent() ist richtig.

      Wenn ich encodeURIComponent verwende, habe ich das gleiche Problem, wie mit meinem Verschlüsselungsumweg encode2(). Also z.B. wird aus einem ä ein ä.

      Daher: Aus welchem Grund ist escape() falsch?

      Und dies funktioniert bei Umlauten nicht. Ein mb_ord("ä") gibt mir zwar 228 aus, aber ein mb_chr(228) oder ein mb_chr(mb_ord("ä")) gibt ä (2 Zeichen!) aus.

      Offenbar ist die Seite, in der du UTF-8-codierte Zeichen ausgibst, nicht mit dieser Codierung an den Browser übertragen worden. Check mal, welches Encoding dir dein Browser in den Seiteninformationen anzeigt.

      Doch, ich hatte zwar ursprünglich Latin1 über einen meta-Tag ausgegeben, aber im Moment habe ich auf UTF-8 gewechselt. Dies wird mir auch vom Firefox bestätigt (View Page Info - Encoding: UTF-8).

      Deine geschriebenen Funktionen sind leider allesamt überflüssig.

      Da ich magic_quotes deaktivieren kann, weiß ich das mittlerweile auch.
      Wie gesagt - ohne meinen Verschlüsselungsumweg und mit escape() vorm Absenden funktioniert's ja jetzt auch.

      1. hi,

        Wenn ich encodeURIComponent verwende, habe ich das gleiche Problem, wie mit meinem Verschlüsselungsumweg encode2(). Also z.B. wird aus einem ä ein ä.

        Daher: Aus welchem Grund ist escape() falsch?

        escape() ist nicht falsch, schau Dir mal an was es macht, das kannst Du in der Browser-Adresszeile schon testen:

        javascript:alert(escape('ä'))
        javascript:alert(encodeURI('ä'))

        Du siehst in der Ausgabe Folgendes:
        escape    => %E4
        encodeURI => %C3%4

        Aus diesen Escape-Sequenzen entstehen serverseitig Bitfolgen, die Bitfolge, die in hex E4 enstspricht ist ein 'ä' wenn es ISO-8859-1 codiert ist. Die Bitfolge C3A4 (2 byte, 16 Bit) entspricht auch einem 'ä' das jedoch UTF-8 codiert ist. E4 ist gleichzeitig auch der Codepoint für das 'ä' im Unicode-System.

        Deine Datei, die serverseitig geschrieben wird, enthält wiederum bytes, je nachdem, wie Du die dem Request mitgibst, sind das für ein 'ä' in ISO 1 byte (escape), in utf8 hingegen 2 byte (encodeURI).

        Gute Nacht,
        Horst Hausmann

      2. Tach,

        Wenn ich encodeURIComponent verwende, habe ich das gleiche Problem, wie mit meinem Verschlüsselungsumweg encode2(). Also z.B. wird aus einem ä ein ä.

        sieht aus, wie ein Perfekter UTF-8-Umlaut, der als ISO-8859-1 angezeigt wird, liefere deine Seite als UTF-8 aus und alles wird gut.

        mfg
        Woodfighter

      3. Moin!

        Als erstes habe ich dabei einfach mein JavaScript den value aus der textarea rausholen lassen, diesen mit escape() verschlüsselt (es darf ja kein & enthalten sein) und als einen (von mehreren) Parametern an die Funktion SendData (siehe unten) gegeben.

        escape() ist die falsche Funktion. encodeURIComponent() ist richtig.

        Wenn ich encodeURIComponent verwende, habe ich das gleiche Problem, wie mit meinem Verschlüsselungsumweg encode2(). Also z.B. wird aus einem ä ein ä.

        Daher: Aus welchem Grund ist escape() falsch?

        escape codiert die Zeichen, die nicht ASCII sind, gemäß ISO-8859-1 - das funktioniert nur mit den Zeichen, die in dieser Codierung existieren, und es spielt absolut nicht gut zusammen mit Ajax, welches sich im Prinzip nur mit UTF-8-Datenaustausch wohlfühlt. ISO-8859-1 und UTF-8 mischen ist aber eine ganz ganz schlechte Idee...

        Anmerkung fürs Protokoll: Ich will nicht ausschließen, dass man das XMLHttpRequest-Objekt unter gewissen Umständen und mit viel Servermitarbeit nicht doch zur geordneten Mitarbeit mit einer ANDEREN Codierung als UTF-8 überreden könnte - aber UTF-8 fällt halt direkt aus der Tüte, ohne Extra-Aufwand, und sollte sowieso die einzig wahre Codierung sein, die man heutzutage verwendet - ohne Klimmzüge.

        Und dies funktioniert bei Umlauten nicht. Ein mb_ord("ä") gibt mir zwar 228 aus, aber ein mb_chr(228) oder ein mb_chr(mb_ord("ä")) gibt ä (2 Zeichen!) aus.

        Offenbar ist die Seite, in der du UTF-8-codierte Zeichen ausgibst, nicht mit dieser Codierung an den Browser übertragen worden. Check mal, welches Encoding dir dein Browser in den Seiteninformationen anzeigt.

        Doch, ich hatte zwar ursprünglich Latin1 über einen meta-Tag ausgegeben, aber im Moment habe ich auf UTF-8 gewechselt. Dies wird mir auch vom Firefox bestätigt (View Page Info - Encoding: UTF-8).

        Meta-Tags sind irrelevant, wenn der Server einen HTTP-Header übermittelt hat.

        Deine geschriebenen Funktionen sind leider allesamt überflüssig.

        Da ich magic_quotes deaktivieren kann, weiß ich das mittlerweile auch.
        Wie gesagt - ohne meinen Verschlüsselungsumweg und mit escape() vorm Absenden funktioniert's ja jetzt auch.

        WENN du escape() benutzt, UND das Ergebnis zurückgespielt an den Browser funktioniert, dann ist die Wahrscheinlichkeit sehr hoch, dass du dich komplett in ISO-8859-1 bewegst, und eben gerade nicht UTF-8 benutzt.

        - Sven Rautenberg

      4. [latex]Mae  govannen![/latex]

        Daher: Aus welchem Grund ist escape() falsch?

        escape() ist deprecated und sollte nicht mehr genutzt werden. ( -> MDC)

        Außerdem hat es diverse Probleme (Comparing escape(), encodeURI(), and encodeURIComponent()); dort insbesondere Summary

        Cü,

        Kai

        --
        Dank Hixies Idiotenbande geschieht grade eben wieder ein Umdenken in Richtung "Mess up the Web". (suit)
        Foren-Stylesheet Site Selfzeug JS-Lookup
        SelfCode: sh:( fo:| ch:? rl:( br:< n4:( ie:{ mo:| va:) js:| de:> zu:) fl:( ss:| ls:?
        1. escape() ist deprecated und sollte nicht mehr genutzt werden. ( -> MDC)

          Okay, danke, Frage beantwortet.
          Ich habe die Sache angepasst, escape() verwende ich nicht mehr. Auch habe ich utf8_decode() aus dem PHP-Script herausgenommen, sodass jetzt UTF-codierte Zeichen auch als solche in die Datei gespeichert werden. Funktioniert soweit auch prima.

          Ich habe jetzt ein ähnliches Problem: Die Übertragung der Daten vom Server zum Client.
          Das PHP-Script enthält zur Sicherheit diese Zeile:
          header('Content-Type: text/plain; charset=utf-8');
          Die Webseite (die die JavaScripts enthält), wird über PHP generiert und enthält diese Zeile:
          header("Content-Type: text/html; charset=utf-8");

          (Darf/muss man eigentlich zwischen utf-8 und dem letzten Anführungszeichen noch mal ein Semikolon setzen?)

          Die Daten, die zum Client übertragen werden sollen, werden vom PHP-Script also mit print ausgegeben und vom Client empfangen (SendData()).
          Unmittelbar vor der Ausgabe der Daten über print lasse ich diese mit utf8_encode() UTF-codieren - wenn ich das nicht mache, werden aus Umlauten Fragezeichen (�).

          Und weil's gerade so viel Spaß macht, wollte ich hier - statt utf8_encode() zu verwenden, meinen Verschlüsselungsumweg probieren. Also mit meiner PHP-Funktion encode2() jedes Zeichen in Zeichencode ausdrücken, getrennt durch Punkte und beim Client mit der JavaScript-Funktion decode2() wieder den ursprünglichen String daraus machen.
          Dabei will mir das PHP-Script folgendes mitteilen:

          <br />  
          <b>Warning</b>:  unpack() [<a href='function.unpack'>function.unpack</a>]: Type N: not enough input, need 4, have 0 in <b>/www/htdocs/...</b> on line <b>222</b><br />  
          <br />  
          <b>Warning</b>:  unpack() [<a href='function.unpack'>function.unpack</a>]: Type N: not enough input, need 4, have 0 in <b>/www/htdocs/...</b> on line <b>222</b><br />
          

          Darunter erscheint dennoch der scheinbar problemlos verschlüsselte (Zeichencodes durch Punkte getrennt) Output.

          Was ist hier los?

          Zeile 222 ist in der Funktion mb_ord() diejenige, die mit $result beginnt.
          Für diese Funktion, siehe erstes Posting im Thread.
          Hier die PHP-Verschlüsselungsfunktion:

          function encode2($input)  
          {  
          $buf = "";  
          for ($i = 0, $size = mb_strlen($input); $i < $size; $i++)  
          {  
          if ($buf != "") $buf .= ".";  
          $buf .= mb_ord($input[$i]);  
          }  
            
          return $buf;  
          }
          
          1. Nachtrag:

            Die Daten, die zum Client übertragen werden sollen, werden vom PHP-Script also mit print ausgegeben und vom Client empfangen (SendData()).
            Unmittelbar vor der Ausgabe der Daten über print lasse ich diese mit utf8_encode() UTF-codieren - wenn ich das nicht mache, werden aus Umlauten Fragezeichen (�).

            Die von mir genannten Umlaute, die erst durch utf8_encode() richtig dargestellt werden, werden mit include aus einer weiteren PHP-Datei geholt.
            Alle Variablen in der "eigentlichen" PHP-Datei, die Sonderzeichen enthalten, werden durch den Gebrauch von utf8_encode() utf-codiert angezeigt.

            Ausführlicher:
            Die PHP-Datei, die Daten an den Client (JavaScript) übertragen soll, nenne ich 1. PHP-Datei. Bevor die Daten mit print gesendet werden, werden sie mit utf8_encode() ins UTF-Format konvertiert. Dabei handelt es sich zum Schluss um 1 Variable, die den gesamten Output enthält und eben mit print ausgegeben wird.
            Über include() wird eine 2. PHP-Datei eingebunden, in der Variablen definiert werden, die über die 1. PHP-Datei auch im Output landen. Diese enthalten auch Sonderzeichen, wie z.B. ä, was hinterher auf der Seite auch als ä dargestellt wird.
            Es gibt aber auch Variablen in der 1. PHP-Datei, die Sonderzeichen enthalten, die im Output landen. Diese Sonderzeichen werden auf der Webseite UTF-codiert angezeigt, also zum Beispiel ä statt ä.
            Testweise habe ich in der 1. PHP-Datei eine Variable mit einem Sonderzeichen definiert:
            $tmp = "ä";
            Ich habe diese Variable $tmp dann dem Ouput hinzugefügt (welcher vor dem print durch utf8_encode() läuft).
            Es wird ä angezeigt.
            Wenn ich diese Zeile aus der 1. PHP-Datei herausnehme und stattdessen mit Copy & Paste in die 2. PHP-Datei einfüge (die 2. PHP-Datei wird mit include() in die 1. PHP-Datei eingebunden) und nichts an der Stelle (in der 1. PHP-Datei) ändere, wo $tmp dem Output angehängt wird, dann wird das gewünschte ä angezeigt. Der Output läuft vor dem print immer noch durch utf8_encode().

            Wie kann es sein, dass ein und der selbe String nur richtig ausgegeben wird, wenn er in einer anderen PHP-Datei steht, die included wird - bzw. wie kann es sein, dass ich die Variablen aus der includeten Datei durch utf8_encode() laufen lassen muss, andere aber nicht?

            Ich habe das Problem scheinbar dadurch gelöst, dass ich die Variablen, die ich in der 1. PHP-Datei nutze, die aus der 2. (includeten) PHP-Datei stammen, bevor sie verarbeitet werden mit utf8_encode() ins UTF-Format konvertiere. Dafür lasse ich den Output in der 1. PHP-Datei vor dem print *nicht* mehr durch utf8_encode() laufen.
            Mit Variablen, die in der 1. PHP-Datei erstellt werden, ist utf8_encode() nicht nötig(?).

            1. Hallo,

              Nachtrag:
              [...]
              Die von mir genannten Umlaute, die erst durch utf8_encode() richtig dargestellt werden, werden mit include aus einer weiteren PHP-Datei geholt.

              mit anderen Worten: Du hast ein Mischmasch verschiedener Codierungen, die du nun einfach in einem Topf wirfst und gut verrührst.
              Meinst du nicht, es wäre einfacher und sinnvoller, alle beteiligten Dateien in einer gemeinsamen Codierung vorzuhalten, beispielsweise UTF-8?

              Alle Variablen in der "eigentlichen" PHP-Datei, die Sonderzeichen enthalten, werden durch den Gebrauch von utf8_encode() utf-codiert angezeigt.

              Das wäre dann überflüssig.

              Über include() wird eine 2. PHP-Datei eingebunden, in der Variablen definiert werden, die über die 1. PHP-Datei auch im Output landen. Diese enthalten auch Sonderzeichen, wie z.B. ä, was hinterher auf der Seite auch als ä dargestellt wird.
              Es gibt aber auch Variablen in der 1. PHP-Datei, die Sonderzeichen enthalten, die im Output landen. Diese Sonderzeichen werden auf der Webseite UTF-codiert angezeigt, also zum Beispiel ä statt ä.

              Also ist dein übergeordnetes PHP-Script anscheinend in UTF-8 codiert, du verkaufst es dem Client aber als ISO-8859-1 oder etwas Verwandtes. Die includierte Datei scheint ihrerseits in ISO-8859-x codiert zu sein.

              $tmp = "ä";
              Ich habe diese Variable $tmp dann dem Ouput hinzugefügt (welcher vor dem print durch utf8_encode() läuft).
              Es wird ä angezeigt.

              Klar, ein "ä" ist in UTF-8 codiert, die zwei Bytes, die es repräsentieren, werden ihrerseits *nochmal* in UTF-8 umcodiert. Da kommt Blödsinn raus.

              Wenn ich diese Zeile aus der 1. PHP-Datei herausnehme und stattdessen mit Copy & Paste in die 2. PHP-Datei einfüge (die 2. PHP-Datei wird mit include() in die 1. PHP-Datei eingebunden) und nichts an der Stelle (in der 1. PHP-Datei) ändere, wo $tmp dem Output angehängt wird, dann wird das gewünschte ä angezeigt. Der Output läuft vor dem print immer noch durch utf8_encode().

              Ja. Ein in ISO codiertes "ä" wird mit utf8_encode() umcodiert und dann als UTF-8 ausgegeben.

              Wie kann es sein, dass ein und der selbe String nur richtig ausgegeben wird, wenn er in einer anderen PHP-Datei steht, die included wird - bzw. wie kann es sein, dass ich die Variablen aus der includeten Datei durch utf8_encode() laufen lassen muss, andere aber nicht?

              Die beiden Dateien verwenden verschiedene Textcodierungen. Sagte ich ja schon.

              Ich habe das Problem scheinbar dadurch gelöst, dass ich die Variablen, die ich in der 1. PHP-Datei nutze, die aus der 2. (includeten) PHP-Datei stammen, bevor sie verarbeitet werden mit utf8_encode() ins UTF-Format konvertiere. Dafür lasse ich den Output in der 1. PHP-Datei vor dem print *nicht* mehr durch utf8_encode() laufen.

              Das ist keine Lösung, das ist Yoga rückwärts mit Überschlag.

              So long,
               Martin

              --
              F: Was ist schlimmer: Alzheimer oder Parkinson?
              A: Parkinson. Lieber mal ein Bier vergessen zu zahlen, als eins verschütten.
              Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
              1. Meinst du nicht, es wäre einfacher und sinnvoller, alle beteiligten Dateien in einer gemeinsamen Codierung vorzuhalten, beispielsweise UTF-8?

                Genau das will ich ja erreichen.

                Also ist dein übergeordnetes PHP-Script anscheinend in UTF-8 codiert, du verkaufst es dem Client aber als ISO-8859-1 oder etwas Verwandtes.

                Wieso sollte es dem Client als Latin1 verkauft werden, nachdem folgende Zeile oben in beiden PHP-Dateien steht?:
                header("Content-Type: text/html; charset=utf-8");

                Die includierte Datei scheint ihrerseits in ISO-8859-x codiert zu sein.

                Das könnte das Verhalten erklären.

                Aber wie gesagt - beide PHP-Dateien verwenden oben zitierte Zeile.

                1. Hi,

                  Meinst du nicht, es wäre einfacher und sinnvoller, alle beteiligten Dateien in einer gemeinsamen Codierung vorzuhalten, beispielsweise UTF-8?
                  Genau das will ich ja erreichen.

                  ja dann tu das doch einfach.

                  Also ist dein übergeordnetes PHP-Script anscheinend in UTF-8 codiert, du verkaufst es dem Client aber als ISO-8859-1 oder etwas Verwandtes.
                  Wieso sollte es dem Client als Latin1 verkauft werden, nachdem folgende Zeile oben in beiden PHP-Dateien steht?:
                  header("Content-Type: text/html; charset=utf-8");

                  vergiss es - diesen Satz schrieb ich, bevor ich deine weiteren Erläuterungen gelesen hatte. Es gilt:

                  $tmp = "ä";
                  Ich habe diese Variable $tmp dann dem Ouput hinzugefügt (welcher vor dem print durch utf8_encode() läuft).
                  Es wird ä angezeigt.
                  Klar, ein "ä" ist in UTF-8 codiert, die zwei Bytes, die es repräsentieren, werden ihrerseits *nochmal* in UTF-8 umcodiert. Da kommt Blödsinn raus.

                  Die includierte Datei scheint ihrerseits in ISO-8859-x codiert zu sein.
                  Das könnte das Verhalten erklären.
                  Aber wie gesagt - beide PHP-Dateien verwenden oben zitierte Zeile.

                  In der includierten Datei ist das natürlich sinnlos, da sie keine eigenständige Ressource ist. Zudem steht es anscheinend im Widerspruch zur tatsächlichen Codierung.

                  So long,
                   Martin

                  --
                  F: Was ist wichtiger: Die Sonne oder der Mond?
                  A: Der Mond. Denn er scheint nachts. Die Sonne dagegen scheint tagsüber, wenn es sowieso hell ist.
                  Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
                  1. ja dann tu das doch einfach.

                    Scheinbar ist es nicht so einfach.

                    Aber wie gesagt - beide PHP-Dateien verwenden oben zitierte Zeile.

                    In der includierten Datei ist das natürlich sinnlos, da sie keine eigenständige Ressource ist. Zudem steht es anscheinend im Widerspruch zur tatsächlichen Codierung.

                    Das verstehe ich nicht.
                    Ich bin auch nicht davon ausgegangen, dass die header-Zeile in der includierten Datei etwas bringt - aber ich habe diese Zeile doch auch in der 1. (eigentlichen) PHP-Datei. Damit müsste doch alles UTF-8-codiert sein?

                    Oder was meinst du mit "tatsächlicher Codierung"?
                    Ich dachte, durch diese header-Zeile in der 1. PHP-Datei setze ich die Codierung auf UTF-8?

                    1. Hallo,

                      ja dann tu das doch einfach.
                      Scheinbar ist es nicht so einfach.

                      doch, eigentlich schon, je nach Editor.

                      In der includierten Datei ist das natürlich sinnlos, da sie keine eigenständige Ressource ist. Zudem steht es anscheinend im Widerspruch zur tatsächlichen Codierung.
                      Das verstehe ich nicht.
                      Ich bin auch nicht davon ausgegangen, dass die header-Zeile in der includierten Datei etwas bringt - aber ich habe diese Zeile doch auch in der 1. (eigentlichen) PHP-Datei. Damit müsste doch alles UTF-8-codiert sein?

                      Nicht unbedingt: Du lässt deinen Server _behaupten_, es sei alles in UTF-8 codiert.

                      Oder was meinst du mit "tatsächlicher Codierung"?

                      Na die, in der die Datei tatsächlich gespeichert wurde.

                      Ich dachte, durch diese header-Zeile in der 1. PHP-Datei setze ich die Codierung auf UTF-8?

                      Nein. Damit änderst du -bildlich gesprochen- nur die Aufschrift auf dem Briefumschlag. Was wirklich drin ist, ändert sich dadurch nicht.

                      Ciao,
                       Martin

                      --
                      Vielseitigkeit: Von vielen Dingen keine Ahnung haben.
                      Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
                      1. Ich dachte, durch diese header-Zeile in der 1. PHP-Datei setze ich die Codierung auf UTF-8?

                        Nein. Damit änderst du -bildlich gesprochen- nur die Aufschrift auf dem Briefumschlag. Was wirklich drin ist, ändert sich dadurch nicht.

                        Bedeutet das, dass die includierte PHP-Datei ISO-codiert sein könnte, obwohl die includierende Datei die genannte header-Zeile (UTF-8) verwendet, weil Zeichen wie Umlaute in der includierten Datei enthalten sind ($tmp = "ä";)?

                        Oder kann ich diese tatsächliche Codierung irgendwie beeinflussen?

                        1. Hi!

                          Oder kann ich diese tatsächliche Codierung irgendwie beeinflussen?

                          In deinem Editor siehst du beim Bearbeiten im Prinzip nur Zeichen. Die Kodierung wird erst beim Abspeichern in eine Datei relevant. Einige Editoren lassen die Kodierung beim Speichern wählen, andere arbeiten gleich in der Zielkodierung und lassen sich beim Bearbeiten umstellen. Und die, die UTF-8 gar nicht richtig können, sind sowieso ungeeignet.

                          Da übrigens auch unter den Programmierern nicht alle den Unterschied zwischen Unicode und UTF-8 kennen, verwenden einige den Begriff Unicode, wenn sie UTF-8 meinen.

                          Lo!

                        2. @@c--:

                          nuqneH

                          Oder kann ich diese tatsächliche Codierung irgendwie beeinflussen?

                          Änderung der Zeichencodierung einer (X)HTML-Seite auf UTF-8. Beginne bei Schritt 1.

                          Als Einführung lies du dir vielleicht Zeichencodierung für Anfänger durch.

                          Qapla'

                          --
                          Gut sein ist edel. Andere lehren, gut zu sein, ist noch edler. Und einfacher.
                          (Mark Twain)
  3. hi,

    Wie kann ich also zuverlässig in PHP einen Zeichencode in das entsprechende Zeichen konvertieren, sodass ich also aus 228 ein ä erhalte?

    Soviel ich weiß, gibts die pack-Funktionen aus der Perl-Welt auch in PHP. In Perl würde das so aussehen:

      
    print pack("U", 228), "\n", pack("C", 228), "\n";  
    
    

    D.h., je nach Schablone wird aus dem Codepoint (228 bzw. E4, U+00E4) die entsprechende byte-Folge erzeugt, in ISO hat damit das 'ä' ein byte, in UTF-8 hingegen 2 byte.

    Horst Hausmann