Christian: Array in UTF-8 kodieren

Hallo!

Ich will die Schlüssel und Werte eines Array in UTf-8 konvertieren. Also das ganze Array eben. Ich hab zuerst an utf8_encode() gedacht, aber das wandelt nur Strings um. Gibt es so eine Funktion auch für Arrays? Bin leider nicht fündig geworden.

best regards

  1. Lieber Christian,

    Du wirst Dein Array Index für Index und Wert für Wert in UTF-8 nachbilden müssen. Dazu wäre es sehr sinnvoll, wenn Du mehr über die Struktur Deines Arrays bekannt geben könntest.

    Am Besten ist es, Du verrätst uns gleich, wofür und warum das Ganze, dann kann man besser verstehen, was Du willst. Und dann kann man Dir besser raten.

    Liebe Grüße,

    Felix Riesterer.

    --
    ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
    1. Hey Felix!

      Du wirst Dein Array Index für Index und Wert für Wert in UTF-8 nachbilden müssen. Dazu wäre es sehr sinnvoll, wenn Du mehr über die Struktur Deines Arrays bekannt geben könntest.

      Mein Array wird dynamisch aus einer Datenbankabfrage erzeugt. Ich kann also vorher nicht wissen wieviel Schlüssel mein Array hat. Jeder Schlüssel ist dann wieder ein Array mit 4 Werten. Denen aus der Datenbankabfrage halt.
      Zu sagen wär noch, dass die DB-Abfrage maximal 7 Ergebnisse liefern kann. Das Ganze bleibt also überschaubar.

      array(  
          array("key1"=>"value1", "key2"=>"value2", "key3"=>"value3", "key4"=>"value4"),  
          array("key1"=>"value1", "key2"=>"value2", "key3"=>"value3", "key4"=>"value4"),  
          array(...),  
          array(...)  
      )
      

      Am Besten ist es, Du verrätst uns gleich, wofür und warum das Ganze, dann kann man besser verstehen, was Du willst. Und dann kann man Dir besser raten.

      Das Problem ist, dass ich auf die Daten aus der Datenbank angewiesen bin und diese gern in UTF-8 hätte. Auf den Inhalt und die Struktur der Datenbank hab ich aber keinen Einfluss (auch nicht wenn ich nett bitten würde^^), deshalb muss ich selbst "Hand anlegen".

      best regards

      1. Lieber Christian,

        Du widersprichst Dir!

        Jeder Schlüssel ist dann wieder ein Array mit 4 Werten.

        array(

        array("key1"=>"value1", "key2"=>"value2", "key3"=>"value3", "key4"=>"value4"),

          
        Kannst Du Dir sicher sein, dass die vier Werte alle vom Typ string sind? Dann könntest Du einfach ein Ersatz Array nachbauen, in dem Du die sieben Arrays der Reihe nach kopierst, wobei Du immer brav ein utf8\_encode() drüberlaufen lässt. Das wird aber scheitern, wenn die Werte "value1" bis "value4" keine Strings sind!  
          
        Liebe Grüße,  
          
        Felix Riesterer.
        
        -- 
        ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
        
        1. Hey Felix!

          Du widersprichst Dir!

          Wobei?

          Kannst Du Dir sicher sein, dass die vier Werte alle vom Typ string sind?

          Nein, vielmehr ist es so, dass die Werte alles sein können. Ausser Arrays und Objekte.

          best regards

          1. echo $begrüßung;

            Kannst Du Dir sicher sein, dass die vier Werte alle vom Typ string sind?
            Nein, vielmehr ist es so, dass die Werte alles sein können. Ausser Arrays und Objekte.

            mysql_fetch_assoc() liefert immer Strings, auch bei nummerischen Feldern, mit der Ausnahme von DB-NULL-Werten.

            echo "$verabschiedung $name";

  2. echo $begrüßung;

    Ich will die Schlüssel und Werte eines Array in UTf-8 konvertieren.

    Dann mach das doch. Genau so. Jeden Schlüssel und jeden Wert.

    Also das ganze Array eben.

    Am besten gleich beim Erstellen. Ansonsten musst du die Elemente mit den Nicht-UTF-8-Schlüsseln entfernen und neu mit UTF-8-Schlüsseln anlegen. Das bringt unter Umständen die Reihenfolge der Elemente durcheinander.

    Zumindest für die Werte kannst du Funktionen verwenden, die alle Array-Elemente durchlaufen (z.B: array_map()).

    Ich hab zuerst an utf8_encode() gedacht, aber das wandelt nur Strings um. Gibt es so eine Funktion auch für Arrays?

    Die Elemente eines Arrays müssen nicht immer nur Strings sein. Auch Zahlen, boolsche Werte und komplexe Strukturen (Arrays, Objekte) können Werte eines Arrays sein. Darauf blind eine Stringfunktion anzuwenden, kann zur Unbrauchbarkeit der Werte führen.

    echo "$verabschiedung $name";

    1. Hey dedlfix!

      Ich will die Schlüssel und Werte eines Array in UTf-8 konvertieren.
      Also das ganze Array eben.

      Am besten gleich beim Erstellen. Ansonsten musst du die Elemente mit den Nicht-UTF-8-Schlüsseln entfernen und neu mit UTF-8-Schlüsseln anlegen. Das bringt unter Umständen die Reihenfolge der Elemente durcheinander.

      Meine DB-Abfrage gibt mir doch schon Datensätze als Array.
      $array = array();
      while($foo = mysql_fetch_assoc($query)){  // $query ist eine gültige MySQL-Abfrage
          $array = array_push($array, $foo);    // mit Ergebnis, nicht NULL
      }
      print_r($array);

      Zumindest für die Werte kannst du Funktionen verwenden, die alle Array-Elemente durchlaufen (z.B: array_map()).

      Vermutlich dürfte das nicht reichen, weil ich die Schlüssel auch in utf8 brauch.

      Ich hab zuerst an utf8_encode() gedacht, aber das wandelt nur Strings um. Gibt es so eine Funktion auch für Arrays?

      Die Elemente eines Arrays müssen nicht immer nur Strings sein. Auch Zahlen, boolsche Werte und komplexe Strukturen (Arrays, Objekte) können Werte eines Arrays sein. Darauf blind eine Stringfunktion anzuwenden, kann zur Unbrauchbarkeit der Werte führen.

      Oh, daran hatte ich auch gar nicht gedacht. Ich müsste also vorher prüfen ob der Wert ein String ist bevor ich utf8_encode(), oder was auch immer, darauf los lasse? Gibt es dafür eine passende Funktion? Auf Anhieb fällt mir da nichts ein. Ich wurschtel mal im Handbuch rum...

      best regards

      1. Lieber Christian,

        Gibt es dafür eine passende Funktion?

        is_string()

        Liebe Grüße,

        Felix Riesterer.

        --
        ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
      2. echo $begrüßung;

        Meine DB-Abfrage gibt mir doch schon Datensätze als Array.
        $array = array();
        while($foo = mysql_fetch_assoc($query)){  // $query ist eine gültige MySQL-Abfrage
            $array = array_push($array, $foo);    // mit Ergebnis, nicht NULL

        Anmerkung zwischendurch: array_push() solltest du nicht verwenden, wenn es ein $array[] = ... auch tut. Zudem ist deine Verwendung fehlerhaft.

        }
        print_r($array);

        Ich dachte, du kannst erst auf höherem Level auf die Daten zugreifen. Aber wenn du sogar noch händisch mit den mysql_*-Funktionen arbeitest, dann hast du doch volle Kontrolle über die Datenbankverbindung, kannst (MySQL ab 4.1 vorausgesetzt) die Zeichenkodierung der Verbindung selbst bestimmen und bekommst die Werte gleich von MySQL UTF-8-kodiert geliefert, weil MySQL bereits die Felddaten umkodiert. mysql_set_charset() bzw. ein SET NAMES-Statement reicht und deine Sorgen sind keine mehr.

        Wenn das nicht geht, dann kannst du an der obigen Code-Stelle ansetzen.

        $result = array(); // Ergebnis-Array
          while ($dbRecord = mysql_fetch_assoc($query)) {
            $oneRecord = array();
            foreach ($dbRecord as $key => $value)
              $oneRecord[utf8_encode($key)] = utf8_encode($value);
            $result[] = $oneRecord;
          }

        echo "$verabschiedung $name";

        1. Hey dedlfix!

          $array = array_push($array, $foo);    // mit Ergebnis, nicht NULL
          Anmerkung zwischendurch: array_push() solltest du nicht verwenden, wenn es ein $array[] = ... auch tut. Zudem ist deine Verwendung fehlerhaft.

          Was ist denn fehlerhaft? Ich dachte ich verwende das richtig.
          Im Handbuch steht auch es hätte den selben Effekt wie $foo[] = $bar.
          Gibt es da einen Unterschied?

          (..) mysql_set_charset() bzw. ein SET NAMES-Statement reicht und deine Sorgen sind keine mehr.

          Ich hab gerade im MySQL Handbuch nachgeschlagen und ja, es scheint so, dass ich meine Sorgen damit auf einen Schlag los wäre. Ist ja super :)
          Leider bin ich aber nicht so fit bei MySQL.
          Wo müsste ich denn das SET NAMES unterbringen? Im SELECT-Statement oder bei mysql_connect("...")? Meine Experimente sind gerade gescheitert.
          Und heißt es dann SET NAMES utf-8 oder SET NAMES utf8 und kommt das utf.. noch in einfache Anführungszeichen?
          Ich hab ein bisschen rum probiert, bekomme aber immer Fehler wie z.B. Warning: mysql_fetch_assoc(): supplied argument is not a valid MySQL result resource

          Wenn das nicht geht, dann kannst du an der obigen Code-Stelle ansetzen.

          Das mit der Datenbank sollte klappen. Wenn ich jetzt noch raus bekomme wie, bin ich erstmal glücklich. Danke auch für den Hinweis, dass mysql_fetch_assoc() (fast) immer Strings zurück gibt.

          best regards

          1. Hey dedlfix!

            Ich denke ich hab die Lösung gefunden.
            Über meinem SELECT-Statement habe ich jetzt mysql_query("SET NAMES 'utf8'", $connect); eingefügt. Die Daten kommen UTF-8 kodiert an.

            Da hab ich am Anfang also in die völlig falsche Richtung gedacht.

            Herzlichen Dank und einen schönen Advent wünsch ich noch!

            best regards

          2. echo $begrüßung;

            $array = array_push($array, $foo);    // mit Ergebnis, nicht NULL
            Was ist denn fehlerhaft? Ich dachte ich verwende das richtig.

            Siehe Handbuch. Das Ergebnis von array_push() ist ein Integerwert. Wenn du den der Array-Variablen zuweist, ist selbiges fort.

            Im Handbuch steht auch es hätte den selben Effekt wie $foo[] = $bar.

            Da steht auch, dass bei einer Ein-Element-Anfügung $foo[] = besser ist.

            (..) mysql_set_charset() bzw. ein SET NAMES-Statement reicht und deine Sorgen sind keine mehr.
            Wo müsste ich denn das SET NAMES unterbringen? Im SELECT-Statement oder bei mysql_connect("...")? Meine Experimente sind gerade gescheitert.

            mysql_set_charset(), wenn das in deiner PHP-Verion vorhanden ist, nach dem mysql_connect() aufrufen. Alternativ das SET NAMES mit mysql_query() am selben Ort.

            Und heißt es dann SET NAMES utf-8 oder SET NAMES utf8 und kommt das utf.. noch in einfache Anführungszeichen?

            utf8 ohne Anführungszeichen geht immer. Mit Anführungszeichen geht es auch. Bei utf-8 bin ich mir grad nicht sicher, aber wenn, dann geht das wegen des Minus-Zeichens nicht ohne Anführungszeichen.

            Ich hab ein bisschen rum probiert, bekomme aber immer Fehler wie z.B. Warning: mysql_fetch_assoc(): supplied argument is not a valid MySQL result resource

            Dann hast du einen Fehler im vorhergehenden mysql_query(), den du nicht auswertest[1]. Das Ignorieren des Funktionsergebnisses ist keine gute Idee und führt zu solchen Folgefehlern. (Das oft gesehene "or die()" ist meist keine angemessene Reaktion.)

            [1] Genauer gesagt, die Fetch-Funktion erwartet den Typ resource, du übergibt aber irgendwas anderes.

            echo "$verabschiedung $name";

            1. Hey Dedlfix!

              $array = array_push($array, $foo);    // mit Ergebnis, nicht NULL
              Was ist denn fehlerhaft? Ich dachte ich verwende das richtig.
              Siehe Handbuch. Das Ergebnis von array_push() ist ein Integerwert. Wenn du den der Array-Variablen zuweist, ist selbiges fort.

              Du meinst "Liefert die neue Anzahl Elemente des Arrays."?
              Also wäre es dann richtig wenn ich nur array_push($array, $foo); ohne vorangestelltes $array= schreiben würde?
              Also mal abgesehen von dem Einwand "Wenn Sie array_push() verwenden, um ein Element an ein Array anzuhängen, ist es besser $array[] =  zu benutzen, da dies den zusätzlichen Aufwand vermeidet, eine Funktion aufzurufen".

              utf8 ohne Anführungszeichen geht immer. Mit Anführungszeichen geht es auch. Bei utf-8 bin ich mir grad nicht sicher, aber wenn, dann geht das wegen des Minus-Zeichens nicht ohne Anführungszeichen.

              Ansonsten ist das Minus-Zeichen als Operator geserviert?

              best regards

              1. echo $begrüßung;

                Also wäre es dann richtig wenn ich nur array_push($array, $foo); ohne vorangestelltes $array= schreiben würde?

                Ja.

                utf8 ohne Anführungszeichen geht immer. Mit Anführungszeichen geht es auch. Bei utf-8 bin ich mir grad nicht sicher, aber wenn, dann geht das wegen des Minus-Zeichens nicht ohne Anführungszeichen.
                Ansonsten ist das Minus-Zeichen als Operator geserviert?

                Ja, das ist mit hoher Wahrscheinlichkeit so.

                Abgesehen davon gibt es im MySQL-Handbuch eine Liste der Charsets. Da ist nicht erwähnt, dass es alternative Schreibweisen mit Bindestrichen gäbe.

                echo "$verabschiedung $name";