Ankündigung

Einklappen
Keine Ankündigung bisher.

Index eines assoziativen Arrays utf-8-kodiert

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Index eines assoziativen Arrays utf-8-kodiert

    Servus,

    ich muss grad mit dem Phänomen kämpfen, dass die Indexe eines Arrays, das aus einer Datenbankabfrage zurückgegeben wird, utf-8-kodiert sind. Soll heißen, ich bekomme über "print_r" die erwartete Ausgabe, aber mit $row['index'] erhalte ich keinen Wert, wo einer sein sollte. Mit $row[utf8_encode('index')] geht's.

    Das Skript selbst ist auch utf-8-kodiert. Auf einem anderen Rechner mit der gleichen xampp-Konfiguration (XP statt Vista) funktioniert's wunderbar. Die Datenbank (Mysql) ist ebenfalls auf utf-8 konfiguriert.

    Habt ihr eine Idee, was da schief läuft?

  • #2
    Es gibt bei Unicode unterschiedliche Darstellungen (und Normalformen) für bestimmte Zeichen. Schau es Dir doch einfach mal auf Byte-Ebene an.
    PHP-Code:
    function foo($s)
    {
      
    $s = (string)$s;
      echo 
    '<tr><th>' $s '</th>';
      for(
    $i=0$i<strlen($s); $i++)
      {
        
    printf('<td>%02X</td>'ord($s[$i]));
      }
      echo 
    "</tr>\n";
    }

    function 
    bar($array$index) {
      echo 
    '<table>';
      
    foo($index);
      foreach(
    $array as $key=>$value)
      {
        
    foo($key);
      }
      echo 
    "</table>\n";
    }

    bar($row'test'); 

    Kommentar


    • #3
      Danke David, ich hab das mal ausprobiert. Leider gleicht der handgeschriebene Index dem realen Index des Arrays:
      PHP-Code:
      function foo($s)
      {
        
      $s = (string)$s;
        echo 
      "\n".$s."    ";
        for(
      $i=0$i<strlen($s); $i++)
        {
          
      printf(" %02X"ord($s[$i]));
        }
      }

      function 
      bar($array$index) {
        foreach(
      $array as $key=>$value)
        {
          
      foo($key);
          echo 
      sprintf(' %s= \'%s\' %s= utf8_encode(\'%s\')'$key == $index '=' '!'$indexutf8_encode($index) == $key '=' '!'utf8_encode($index));
        }
      }

      echo 
      '<pre>';
      $pdo = new PDO('mysql:host=localhost;dbname=phplib''phplib''phplib');
      $pdo->query('set names \'utf8\'');
      $queryStr 'select * from user limit 1';
      $result $pdo->query($queryStr);
      while(
      $row $result->fetch(PDO::FETCH_ASSOC)) {
          echo 
      "print_r(\$row):\n";
          
      print_r($row);
          echo 
      "\necho \$row['user_id']: ".$row['user_id'];
          echo 
      "\necho \$row[utf8_encode('user_id')]: ".$row[utf8_encode('user_id')];
          echo 
      "\n\nBytes von 'user_id': ";
          
      foo('user_id');
          echo 
      "\nBytes von utf8_encode('user_id'): ";
          
      foo(utf8_encode('user_id'));
          echo 
      "\n\nBytes von Indexen per foreach:";
          
      bar($row'user_id');
          
      //print_r($row);
      }
      echo 
      '</pre>'
      Ausgabe:
      Code:
      print_r($row):
      Array
      (
          [user_id] => 1
          [username] => root
          [password] => root
          [email] => 
      )
      
      echo $row['user_id']: 
      echo $row[utf8_encode('user_id')]: 1
      
      Bytes von 'user_id': 
      user_id     75 73 65 72 5F 69 64
      Bytes von utf8_encode('user_id'): 
      user_id     75 73 65 72 5F 69 64
      
      Bytes von Indexen per foreach:
      user_id     75 73 65 72 5F 69 64 == 'user_id' == utf8_encode('user_id')
      username     75 73 65 72 6E 61 6D 65 != 'user_id' != utf8_encode('user_id')
      password     70 61 73 73 77 6F 72 64 != 'user_id' != utf8_encode('user_id')
      email     65 6D 61 69 6C != 'user_id' != utf8_encode('user_id')
      Wie du siehst, hat 'user_id' dieselbe Byterepräsentation wie das utf8-kodierte 'user_id', aber trotzdem bekomme ich nur mit letzterem den Wert aus dem Array.
      Sämtliche Applikationsressourcen (Datenbank, Code) sind auf utf8 gesetzt. Du wirst wahrscheinlich Schwierigkeiten haben, das zu reproduzieren

      Kommentar


      • #4
        Da ist mir offen gesagt zuviel utf8_irgendwas drin.
        Bitte nochmal so versuchen
        PHP-Code:
        <?php
        function foo($s)
        {
          
        $s = (string)$s;
          echo 
        '<tr><th>' $s '</th>';
          for(
        $i=0$i<strlen($s); $i++)
          {
            
        printf('<td>%02X</td>'ord($s[$i]));
          }
          echo 
        "</tr>\n";
        }

        function 
        bar($array$index) {
          echo 
        '<table>';
          
        foo($index);
          foreach(
        $array as $key=>$value)
          {
            
        foo($key);
          }
          echo 
        "</table>\n";
        }

        $pdo = new PDO('mysql:host=localhost;dbname=phplib''phplib''phplib');
        $pdo->query('set names \'utf8\'');
        $queryStr 'select * from user limit 1';
        $result $pdo->query($queryStr);
        $row $result->fetch(PDO::FETCH_ASSOC);
        bar($row'user_id');

        Kommentar


        • #5
          Zitat von David Beitrag anzeigen
          Da ist mir offen gesagt zuviel utf8_irgendwas drin.
          Vertrau mir Das ist nur eine erweiterte Gegenüberstellung, nachdem ich deine schlanke Variante ausprobiert habe. Diese zeigt mir nämlich, dass der Index im Array und mein handgeschriebener die gleiche Bytefolge haben.

          Wenn ich meinen handgeschriebenen Index mit "utf8_encode" formatiere, hat er ebenfalls die gleiche Bytefolge. Das bedeutet doch, dass der String schon von Haus aus utf8-kodiert ist, oder? Aber dann kann ich den Wert aus dem Array holen.

          Welchen Einfluss haben denn PDO und die Datenbank auf die Schlüssel das Arrays? Landet der Zeichensatz der Datenbankverbindung direkt im Array, also die Spaltenbezeichner des Abfrageergebnis'?

          Kommentar


          • #6
            Zitat von Normalo Beitrag anzeigen
            Vertrau mir
            Ungern, ich kenne Dich ja nicht
            Zitat von Normalo Beitrag anzeigen
            Das ist nur eine erweiterte Gegenüberstellung, nachdem ich deine schlanke Variante ausprobiert habe. Diese zeigt mir nämlich, dass der Index im Array und mein handgeschriebener die gleiche Bytefolge haben.
            Dann weiss ich auch nicht weiter.

            Kommentar

            Lädt...
            X