0

I feel like I am missing something obvious trying to access key 784 in an array. Consider the following code:


    $cart_str = isset($_COOKIE['cart'])?$_COOKIE['cart']:"{}";
    echo $cart_str . "\n\n";
    $cart_arr = (array) json_decode($cart_str);

    var_dump($cart_arr);
    var_dump($cart_arr['784']);
    var_dump($cart_arr[784]);

This is the output from the above:

{"780":{"qty":"1","pid":"780"},"784":{"qty":"1","pid":"784"},"794":{"qty":"1","pid":"794"}}<br>array(3) {
  ["780"]=>
  object(stdClass)#3 (2) {
    ["qty"]=>
    string(1) "1"
    ["pid"]=>
    string(3) "780"
  }
  ["784"]=>
  object(stdClass)#4 (2) {
    ["qty"]=>
    string(1) "1"
    ["pid"]=>
    string(3) "784"
  }
  ["794"]=>
  object(stdClass)#5 (2) {
    ["qty"]=>
    string(1) "1"
    ["pid"]=>
    string(3) "794"
  }
}
<br />
<b>Notice</b>:  Undefined offset: 784 in <b>C:\Users\John\Dropbox\htdocs\uzepi_com_test\cart.php</b> on line <b>34</b><br />
NULL
<br />
<b>Notice</b>:  Undefined offset: 784 in <b>C:\Users\John\Dropbox\htdocs\uzepi_com_test\cart.php</b> on line <b>35</b><br />
NULL

I was expecting to get an object printed out that looked like this corresponding item in the array with key 784.

  • Instead of `var_dump()` try `var_export()` to create your question. That way we can see what the code looks like to create the "array" you have. – KIKO Software Mar 29 '23 at 00:09
  • @KIKO Software , I added var_export($cart_arr['784']); as you suggested, but unfortunately I just got the exact same 'Undefined offset' notice; However, since no one has answered yet, I added some more context to show how the array was created. – eclectic_123 Mar 29 '23 at 00:25
  • Yes, of course you get the same error. I was interested in `var_export($cart_arr);`, because it looks like you've got an object and not an array. But the code helps. Can you try `$cart_arr = json_decode($cart_str, true);` instead of `$cart_arr = (array) json_decode($cart_str);`? That should really yield you an array. – KIKO Software Mar 29 '23 at 00:29
  • I would still like to see the original JSON. That is the `$cart_str`, because adding the `true` in `json_decode()` will turn all objects into array and that might not be what you want. – KIKO Software Mar 29 '23 at 00:37
  • @KIKO Software , I added the $cart_str – eclectic_123 Mar 29 '23 at 00:52
  • Yes, thank you. I tried your code, and I get a different result. See: https://3v4l.org/eZ1ps – KIKO Software Mar 29 '23 at 00:57
  • Before I see that, Let me tell you, I added true to the json_decode parameter and it seems that fixed it. Let me double check. Professional curiosity, I'm still curious about the original question, I never seen anything like this where vardump shows an array with keys but cannot access the array as shown in var_dump. Well actually, I mostly use print_r, but anyway, If anyone else wants to comment I will be curious to know why this is for learning purposes.. – eclectic_123 Mar 29 '23 at 00:58
  • It looks like this was the expected result up until PHP7.2, see: https://3v4l.org/gTToo You should _really_ upgrade your PHP version. – Sammitch Mar 29 '23 at 01:00
  • Ah, I did test 7.4, but not lower than that. So, the answer is basically that your PHP version is too old... – KIKO Software Mar 29 '23 at 01:02
  • It's something to do with casting the object to an array. Unless you have a very specific reason why you're doing that, don't do that. – Sammitch Mar 29 '23 at 01:04
  • Casting to an array is the only solution if you want to keep the objects in the array (in PHP > 7.2). In all other case use the `true` inside the `json_decode()`. PHP does not accept numbers as property names in objects, I think. – KIKO Software Mar 29 '23 at 01:05
  • 1
    Guys, I am developing on an old laptop with way old version of php before 7.2. Woops. @KIKO Software "PHP does not accept numbers as property names in objects, I think." I suspect you are right this is why I want to keep as array. These are my product IDs. – eclectic_123 Mar 29 '23 at 01:12

1 Answers1

1

Your problem is this line:

$cart_arr = (array) json_decode($cart_str);

Which triggers known buggy behaviour in PHP<7.2:

Implemented "Convert numeric keys in object/array casts" RFC, fixes bugs #53838, #61655, #66173, #70925, #72254, etc.

You can iterate those keys if you really need to, but you cannot access them directly. I believe that it has something to do with type juggling, eg: it will always juggle "784" to 784 and that index doesn't technically exist.

First and foremost: Upgrade your PHP installation. Most generously, PHP 7.1 was EOLed in Dec 2019.

Second: Do not cast the object to an array when you can simply ask json_decode() to return an array instead.

$cart_arr = json_decode($cart_str, true);

If you really need that to be an array of objects for some reason, then you can convert it like so:

$data = [];
foreach(json_decode($json) as $key => $value) {
    $data[$key] = $value;
}

Which will work across virtually all versions of PHP.

Sammitch
  • 30,782
  • 7
  • 50
  • 77
  • Adding true to json_decode was a quick fix for me. Regarding upgrading. I have old legacy code that I use almost daily, and upgrading (and possibly breaking something) in this code base is daunting for me, but do plan to follow instructions I found here for updating PHP in xammp: https://stackoverflow.com/questions/2154762/upgrading-php-in-xampp-for-windows/26483387#26483387 which, according to author, can be done while "Keep[ing] back up of PHP folder which is in installed XAMPP directory. You can backup it like changing the PHP folder name to PHP-old or like PHP-version-number"-3/29/23 – eclectic_123 Mar 29 '23 at 14:40