Undefined offset while accessing array element which exists

后端 未结 7 1308
日久生厌
日久生厌 2020-12-15 04:03

I have an array and PHP and when I print it out I can see the values I need to access, but when I try accessing them by their key I am getting a PHP Notice. I printed the ar

7条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-15 04:31

    The problem arises when casting to array an object that has string keys that are valid integers.

    If you have this object:

    object(stdClass)#1 (2) {
      ["207"]=>
      string(3) "sdf"
      ["210"]=>
      string(3) "sdf"
    }
    

    and you cast it with

    $array = (array)$object
    

    you get this array

    array(2) {
      ["207"]=>
      string(3) "sdf"
      ["210"]=>
      string(3) "sdf"
    }
    

    which has keys that can only be accessed by looping through them, since a direct access like $array["207"] will always be converted to $array[207], which does not exist.

    Since you are getting an object like the one above from json_decode() applied to a string like

    $json = '{"207":"sdf", "210":"sdf"}'
    

    The best solution would be to avoid numeric keys in the first place. These are probably better modelled as numeric properties of an array of objects:

    $json = '[{"numAttr":207, "strAttr":"sdf"}, {"numAttr":210, "strAttr":"sdf"}]'
    

    This data structure has several advantages over the present one:

    1. it better reflects the original data, as a collection of objects which have a numeric property
    2. it is readily extensible with other properties
    3. it is more portable across different systems (as you see, your current data structure is causing issues in PHP, but if you should happen to use another language you may easily encounter similar issues).

    If a property → object map is needed, it can be quickly obtained, e.g., like this:

    function getNumAttr($obj) { return $obj->numAttr; } // for backward compatibility
    $arr = json_decode($json); // where $json = '[{"numAttr":...
    $map = array_combine(array_map('getNumAttr', $arr), $arr);
    

    The other solution would be to do as ascii-lime suggested: force json_decode() to output associative arrays instead of objects, by setting its second parameter to true:

    $map = json_decode($json, true);
    

    For your input data this produces directly

    array(2) {
      [207]=>
      string(3) "sdf"
      [210]=>
      string(3) "sdf"
    }
    

    Note that the keys of the array are now integers instead of strings.

    I would consider changing the JSON data structure a much cleaner solution, though, although I understand that it might not be possible to do so.

提交回复
热议问题