PHP Zugriff auf array nach serialisisieren nicht mehr möglich

mercsen

Lt. Commander
Registriert
Apr. 2010
Beiträge
1.679
Moin meine CBler,

diesesmal melde ich mich mit einem absolut unverständlichem Verhalten von PHP.

Ich habe eine Klasse geschrieben die den Login eines users verwaltet und in einer eigenen Klasse dann die Rechte verwaltet. Um diese nicht immer aus der Datenbank laden zu müssen speichere ich das Login Objekt und damit auch das Rechte Objekt in der Session.
Beide Klassen implementieren das Interface serializable und de- / serialisieren wie gewollt.

die Rechte werden in dem Rechte Objekt in einem 2 dimensionalem Array gespeichert nach dem Schema:
Code:
Array {
    ['NIEDERLASSUNG_ID_1'] => Array {
                                                      ['recht1'] => 0,
                                                      ['recht2'] => 1
                                                 },
    ['NIEDERLASSUNG_ID_2'] => Array {
                                                      ['recht1'] => 0,
                                                      ['recht2'] => 0
                                                 }
}
für jede Niederlassung gibt es die selben rechte und jeder user kann beliebig vielen niederlassungen angehören und je nachdem verschiedene rechnte habe.

die niederlassungsid wird als string / assoziativer array gespeichert!

ich serialisiere indem ich die objekte per json_encode in einen json string konvertiere.
beim deserialisieren wird dann der string mit json_decode und dem anpassen einiger werte wieder ein Objekt erzeugt.

Klappt alles wunderbar, bis auf die tatsache das json_encode statt arrays stdObjekte erzeugt, aber das noch das kleinere übel.

viel schlimmer ist das es mir unmöglich ist gezielt auf den deserialisierten Array zuzugreifen!
Weder über den zugriff mit eckigen Klammern $this->rechte[], noch über ein Objekt zugriff mit -> (was mir auch nichts nützen würde....)

ich kann problemlos mit foreach durch die array kays iterieren, aber da zeigt sich schon komisches verhalten!

Code:
        var_dump($niederlassungId);
        echo '<hr>';

        $t = array_keys($this->rechte);
        
        foreach($t as $v) {
            var_dump($v) . "<br>";
            
            echo $v == $niederlassungId ? 'Gleich' : 'Nicht gleich';
            echo '<br>';
            var_dump($this->rechte[$v]);
            echo "<hr>";
        }

erzeugt folgende ausgabe:

Code:
string(1) "1"
--------------------
string(1) "1"
Gleich
NULL
---------------------
string(1) "2"
Nicht gleich
NULL
---------------------
string(3) "999"
Nicht gleich
NULL

obwohl ich den key über eine iteration der arrays keys bekomme erhalte ich trotzdem keinen zugriff, da stimmt doch was nicht.....

hier mal nen var_dump von $this->rechte

Code:
array(3) {
  ["1"]=>
  object(stdClass)#9 (4) {
    ["projekt_sehen"]=>
    string(1) "1"
    ["projekt_bearbeiten"]=>
    string(1) "1"
    ["projekt_mietwagen_sehen"]=>
    string(1) "1"
    ["projekt_mietwagen_bearbeiten"]=>
    string(1) "1"
  }
  ["2"]=>
  object(stdClass)#10 (4) {
    ["projekt_sehen"]=>
    string(1) "0"
    ["projekt_bearbeiten"]=>
    string(1) "0"
    ["projekt_mietwagen_sehen"]=>
    string(1) "0"
    ["projekt_mietwagen_bearbeiten"]=>
    string(1) "0"
  }
  ["999"]=>
  object(stdClass)#11 (4) {
    ["projekt_sehen"]=>
    string(1) "0"
    ["projekt_bearbeiten"]=>
    string(1) "0"
    ["projekt_mietwagen_sehen"]=>
    string(1) "0"
    ["projekt_mietwagen_bearbeiten"]=>
    string(1) "0"
  }
}

übrigens gleiches verhalten bei einer normalen foreach iteration:

Code:
 foreach($this->rechte as $r => $rr) {
            echo "$r --> $rr <br>";
            echo isset($this->rechte[$r]) ? 'Isset' : 'is not set ';
            echo '<br>';
            echo $r == $niederlassungId ? 'Gleich' : 'Nicht gleich';
            echo '<hr>';
        }

erzeugt:

Code:
1 -->  
is not set 
Gleich
------------------------
2 -->  
is not set 
Nicht gleich
-------------------------
999 -->  
is not set 
Nicht gleich

jemand ne idee?
 
Zuletzt bearbeitet:
Folgender Code (sollte selbsterklärend sein):

PHP:
$bla = Array (
            'NIEDERLASSUNG_ID_1' => Array (
                'recht1' => 0,
                'recht2' => 1
            ),
            'NIEDERLASSUNG_ID_2' => Array (
                'recht1' => 0,
                'recht2' => 0
            )
        );

        $blubb = json_encode($bla);

        $foo = json_decode($blubb);
        var_dump($foo);
        var_dump($foo->NIEDERLASSUNG_ID_1);

        $foo = (array) $foo;
        var_dump($foo);
        var_dump($foo['NIEDERLASSUNG_ID_1']);

Erzeugt bei mir folgende Ausgabe:

Code:
object(stdClass)[276]
  public 'NIEDERLASSUNG_ID_1' => 
    object(stdClass)[271]
      public 'recht1' => int 0
      public 'recht2' => int 1
  public 'NIEDERLASSUNG_ID_2' => 
    object(stdClass)[274]
      public 'recht1' => int 0
      public 'recht2' => int 0

object(stdClass)[271]
  public 'recht1' => int 0
  public 'recht2' => int 1

array
  'NIEDERLASSUNG_ID_1' => 
    object(stdClass)[271]
      public 'recht1' => int 0
      public 'recht2' => int 1
  'NIEDERLASSUNG_ID_2' => 
    object(stdClass)[274]
      public 'recht1' => int 0
      public 'recht2' => int 0

object(stdClass)[271]
  public 'recht1' => int 0
  public 'recht2' => int 1

Also der Fehler muss bei dir liegen. Aber warum nicht gleich serialize() / unserialize()?

Wo füllst du denn das Array "rechte".. es sieht so aus, als würde er in dem Objekt die Properties aufgrund der [] falsch anlegt. Oder es wird nur komisch ausgegeben.


EDIT:

Achso, du hast nur Ids als KEY. Da geht natürlich mit json_encode und json_decode nicht, weil JSON alles als OBJEKTE behandelt und dann Klassen mit Properties als Zahlen erstellt werden sollen. Das geht natürlich nicht (Namenskonventionen).
 
Zuletzt bearbeitet:
Gib bei json_decode() als zweites Argument "true" an, dann bekommst du wieder ein Array heraus statt eines Objekts.
 
wie das var_dumpvon $this->rechte zeigte lasse ich es bereits als array erzeugen ;)

naja wie trialgod sagte liegts daran das ich nur zahlen als key setze (die eigentlich strings sind) und da knallts.
Irgendwie schafft json_encode es tatsächlich objekte zu erzeugen die als attribute eine zahl haben, da mir dort aberkeine fehlermeldung um die ohren geflogen ist dachte ich das es ziemlich schnuppe ist, bzw. da ich das Objekt anschließend zum array gecastet habe dachte ich der wandelt die dann in einen assoztiativen array um, da er das objekt aber gar nicht auslesen kann klappt das nicht. den zweiten parameter bei json_decode habe ich noch nie gesehen gehabt, der hats aber gerissen :)

mich würde dieses verhalten halt mal interessieren wie php das hinbekommt und wieso ich über die keys iteieren aber über diese dann nicht zugreifen kann, finde das ein ziemlich inkonsistentes verhalten!

ich hab ziwschendurch auch mal scherzhafterweise selbernen code evaluiert der objekte mit zahlen als attribute definieren sollte, macht der interpreter aber net mit :(
 
Zuletzt bearbeitet:
Hier wird das in einem Nebensatz dokumentiert:
http://www.php.net/manual/en/language.types.array.php#language.types.array.casting

If an object is converted to an array, the result is an array whose elements are the object's properties. The keys are the member variable names, with a few notable exceptions: integer properties are unaccessible; private variables have the class name prepended to the variable name; protected variables have a '*' prepended to the variable name. These prepended values have null bytes on either side. This can result in some unexpected behaviour:
PHP:
<?php

$test = array(
"1" => "muhkuh",
"77" => "blabla",
"haha" => "hihi",
);

var_dump($test[1]);
var_dump($test["77"]);
var_dump($test["haha"]);

$test_obj = (object)$test;
var_dump($test_obj);
var_dump($test_obj->{1});
var_dump($test_obj->{"77"});
var_dump($test_obj->haha);
var_dump($test_obj->{haha});

$test_arrayobj = new ArrayObject($test);
var_dump($test_arrayobj);
var_dump($test_arrayobj->{1});
var_dump($test_arrayobj->{"77"});
var_dump($test_arrayobj->haha);
var_dump($test_arrayobj->{haha});
PHP:
string(6) "muhkuh"
string(6) "blabla"
string(4) "hihi"
object(stdClass)#1 (3) {
  [1]=>
  string(6) "muhkuh"
  [77]=>
  string(6) "blabla"
  ["haha"]=>
  string(4) "hihi"
}
NULL
NULL
string(4) "hihi"
string(4) "hihi"
object(ArrayObject)#2 (3) {
  [1]=>
  string(6) "muhkuh"
  [77]=>
  string(6) "blabla"
  ["haha"]=>
  string(4) "hihi"
}
NULL
NULL
NULL
NULL
 
Zurück
Oben