Ankündigung

Einklappen
Keine Ankündigung bisher.

PHP und JSON, stolperfalle bei numerischen Arrays

Einklappen

Neue Werbung 2019

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

  • PHP und JSON, stolperfalle bei numerischen Arrays

    Folgendes ist mir nach langer Fehlersuche aufgefallen:

    Löscht man in PHP ein Element eines numerischen Arrays und verarbeitet man dieses mittels json_encode weiter, so wird das Array als Objekt abgespeichert, scheinbar weil eben ein Index fehlt.
    Möchte man trotzdem immer noch ein Array erhalten, dann muss man nochmals mittels array_values die Indices neu erstellen. In Javascript stolpert man über das Problem nicht, bzw. nur wenn
    man ein Array-Element mittels delete löscht, was dann ein null als "Loch" zur Folge hat:

    PHP-Code:
    <?php

    $my_array 
    = array( 1234);

    var_dumpjson_encode$my_array ) ); echo "<br /><br />";   //string(11) "[1,2,3,4,5]"

    unset( $my_array[2] );

    var_dumpjson_encode$my_array ) ); echo "<br /><br />"//string(25) "{"0":1,"1":2,"3":4,"4":5}"    <------- Hier ein OBJEKT

    $my_array array_values$my_array );

    var_dumpjson_encode$my_array ) ); echo "<br /><br />"//string(9) "[1,2,4,5]"


    ?>


    <script type="text/javascript">

    var my_array = [ 1, 2, 3, 4, 5 ];

    console.log( JSON.stringify( my_array ) ); //[1,2,3,4,5]

    my_array.shift();

    console.log( JSON.stringify( my_array ) ); //[2,3,4,5]

    delete my_array[2];

    console.log( JSON.stringify( my_array ) ); //[2,3,null,5]   <---- Hier ein Loch

    </script>

  • #2
    ja das ist so.
    [I]You know, my wife sometimes looks at me strangely. „Duncan“, she says, „there's more to life than Solaris“. Frankly, it's like she speaks another language. I mean, the words make sense individually, but put them together and it's complete nonsense.[/I]

    Kommentar


    • #3
      Siehe auch https://de.wikipedia.org/wiki/Json

      Kommentar


      • #4
        Du bekommst doch dein Array zurück wenn du möchtest:
        PHP-Code:
        $my_array = array( 1234);
        unset( 
        $my_array[2] );

        $json json_encode$my_array );
        $arrayCopy json_decode($json,true);  //true für ein Array !

        var_dump($my_array === $arrayCopy); //bool(true) 

        Kommentar


        • #5
          json_decode($json,true) funktioniert bei einem solchen Beispiel natürlich. Ich aber habe ein Mehrdimensionales Array das auch tatsächlich gewollt Objekte drin hat.

          Kommentar


          • #6
            Dann solltest du auch ein solches Beisiel zeigen und nicht so ein Pipifax wie array(1,2,3).

            Kommentar


            • #7
              Zitat von Nightflyer Beitrag anzeigen
              Möchte man trotzdem immer noch ein Array erhalten, dann muss man nochmals mittels array_values die Indices neu erstellen.
              Um Elemente aus einem "numerischen Array" zu löschen sollte man auch array_splice nutzen.
              [SIZE="1"]Atwood's Law: any application that can be written in JavaScript, will eventually be written in JavaScript.[/SIZE]

              Kommentar


              • #8
                Zitat von jspit Beitrag anzeigen
                Du bekommst doch dein Array zurück wenn du möchtest:
                PHP-Code:
                $my_array = array( 1234);
                unset( 
                $my_array[2] );

                $json json_encode$my_array ); 
                Das Problem hierbei ist die Weiterverarbeitung im JavaScript. Dort ist das jetzt nämlich kein Array mehr.
                [SIZE="1"]Atwood's Law: any application that can be written in JavaScript, will eventually be written in JavaScript.[/SIZE]

                Kommentar


                • #9
                  Zitat von lottikarotti Beitrag anzeigen
                  Um Elemente aus einem "numerischen Array" zu löschen sollte man auch array_splice nutzen.
                  Wenn man das für JSON oder irgendein anderes Format braucht, dass keine assoziativen Schlüssen unterstützt, ja, sonst i.d.R. halt nicht.
                  [I]You know, my wife sometimes looks at me strangely. „Duncan“, she says, „there's more to life than Solaris“. Frankly, it's like she speaks another language. I mean, the words make sense individually, but put them together and it's complete nonsense.[/I]

                  Kommentar


                  • #10
                    Da PHP und JavaScript unter "Array" etwas anderes verstehen, gibt es viele Fälle, die beachtet gehören. Wenn man sichergehen will, sollte man mit einem DTO oder eigenem Serializer arbeiten, das/der dafür sorgt, dass die Werte im gewünschten Format vorliegen.

                    Kommentar


                    • #11
                      Zitat von lottikarotti Beitrag anzeigen
                      Das Problem hierbei ist die Weiterverarbeitung im JavaScript. Dort ist das jetzt nämlich kein Array mehr.
                      Das Unterschiede bestehen ist klar, kann jedoch nicht so richtig erkennen wo hier (#1) das Problem liegt.
                      Intern ist ja in Javascript fast alles ein Object, so auch ein Array:
                      Code:
                      alert(typeof( [ 1, 2, 3 ]));  //object
                      Und um in Javasript ein Arrayelement zu entfernen ist delete ja nicht geeignet (z.B. wird die Arraylänge nicht reduziert).
                      Besser ist dafür ja auch splice zu nehmen, womit Elemente echt entfernt werden können.


                      Kommentar


                      • #12
                        Zitat von jspit Beitrag anzeigen
                        Das Unterschiede bestehen ist klar, kann jedoch nicht so richtig erkennen wo hier (#1) das Problem liegt.
                        Intern ist ja in Javascript fast alles ein Object, so auch ein Array:
                        Code:
                        alert(typeof( [ 1, 2, 3 ])); //object
                        Das Problem ist:

                        PHP-Code:
                        $array = [1234];
                        unset(
                        $array[1]);
                        echo 
                        json_encode($array);
                        // = "{"0":1,"2":3,"3":4}" 
                        vs

                        PHP-Code:
                        $array = [1234];
                        array_splice($array11);
                        echo 
                        json_encode($array);
                        // = "[1,3,4]" 
                        Wenn hier ein Array ausgeliefert werden soll, muss der Server das sicherstellen (bspw. wie von hellbringer vorgeschlagen durch einen eigenen Serializer der solche Probleme behebt). Ansonsten hast du clientseitig eben kein Array.
                        [SIZE="1"]Atwood's Law: any application that can be written in JavaScript, will eventually be written in JavaScript.[/SIZE]

                        Kommentar


                        • #13
                          Ok, jetzt hab ich es verstanden. Wenn die clientseitige Anwendung nur mit Arrays und nicht mit Objekten zurechtkommt und man dies clientseitig nicht selbst in der Hand hat muss es halt der Server richten.

                          Per Javasript ein Array aus einem Objekt zu erstellen ist aber auch kein Thema. Dazu mal ein Beispiel welches Objekte enthält:
                          Code:
                          var json =' {"0":1,"2":3,"3":{"key":"text"}}';
                          
                          var obj = JSON.parse(json);
                          
                          var arr = [];
                          for(var i in  obj){
                            arr.push(obj[i]);
                          }
                          
                          console.log(arr); //[1, 3, {…}]

                          Kommentar


                          • #14
                            https://developer.mozilla.org/de/doc.../Object/values

                            Kommentar

                            Lädt...
                            X