Home > Net >  Failed to extract array data so inside of the loop body
Failed to extract array data so inside of the loop body

Time:11-12

I need to loop through a multidimensional array and extract all the data:

PHP code:

//Loads the data and transforms it into an array
$json_data = json_decode(file_get_contents('data.json'));

//Loops through the array and returns the values
echo '<br>'.'Modal: ' .$json_data->list[0]->mode;
echo '<br>'.'Variation: ' .$json_data->list[0]->change;
foreach ($json_data->list[0]->expiry as $data) {
        echo '<br>'.'Due date: ' .$data->cdexpiry;
        echo '<br>'.'Value: ' .$data->vlexpiry;
}

JSON data:

{
    "list": [
        {
            "expiry": [
                {
                    "cdexpiry": "v130",
                    "vlexpiry": "33528.99"
                },
                {
                    "cdexpiry": "v230",
                    "vlexpiry": "21648.39"
                },
                {
                    "cdexpiry": "v150",
                    "vlexpiry": "185350.30"
                }
            ],
            "mode": "0401",
            "change": "N"
        },
        {
            "expiry": {
                "cdexpiry": "v40",
                "vlexpiry": "1091.46"
            },
            "mode": "1904",
            "change": "N"
        },
        {
            "expiry": {
                "cdexpiry": "v770",
                "vlexpiry": "1001.56"
            },
            "mode": "1904",
            "change": "N"
        },
        {
            "expiry": [
                {
                    "cdexpiry": "v130",
                    "vlexpiry": "2084.08"
                },
                {
                    "cdexpiry": "v260",
                    "vlexpiry": "28362.31"
                }
            ],
            "mode": "0213",
            "change": "N"
        },
        {
            "expiry": {
                "cdexpiry": "v210",
                "vlexpiry": "296.78"
            },
            "mode": "0101",
            "change": "N"
        },
        {
            "expiry": [
                {
                    "cdexpiry": "v245",
                    "vlexpiry": "1495.37"
                },
                {
                    "cdexpiry": "v248",
                    "vlexpiry": "1440.37"
                }
            ],
            "mode": "0217",
            "change": "N"
        }
    ],
    "type": "8"
}

I've used a few for's and if's - but I'm missing something.

for ($i = 0; $i < count($json_data->list); $i  ) {
if(isset($json_data->list[$i]->expiry))

Desired Outcome

Type Value
Modal 0401
Variation N
Due date v130
Value 33528.99
Due date v230
Value 21648.39
Due date v150
Value 185350.30
--- ---
Modal 1904
Variation N
Due date V40
Value 1091.46
Due date v770
Value 1001.56
--- ---
Modal 0213
Variation N
Due date v130
Value 2084.08
Due date v260
Value 28362.31
--- ---
Modal 0101
Variation N
Due date V210
Value 296.78
--- ---
Modal 0217
Variation N
Due date V245
Value 1495.37
Due date V248
Value 1440.37

This is the original XML query return file link

I need to extract all the data from the array to be able to manipulate it later. I count on the masters' help!

CodePudding user response:

Unfortunately, you have an inconsistent array structure, so not only do need to write loops to access each layer, you need to write a condition to accommodate the deviated subset structures.

Code: (Demo click the eye icon to render the html output)

$json_data = json_decode($json);
echo "<table border=1>\n";
    echo "\t<tr><td>Type</td><td>Value</td></tr>\n";
    foreach ($json_data->list as $list) {
        echo "\t<tr><td>Modal</td><td>{$list->mode}</td></tr>\n";
        echo "\t<tr><td>Variation</td><td>{$list->change}</td></tr>\n";
        foreach ($list as $key => $data) {
            if ($key === 'expiry') {
                if (is_array($data)) {
                    foreach ($data as $prop) {
                        echo "\t<tr><td>Due date</td><td>$prop->cdexpiry</td></tr>\n";
                        echo "\t<tr><td>Value</td><td>$prop->vlexpiry</td></tr>\n";
                    }
                } else {
                    echo "\t<tr><td>Due date</td><td>$data->cdexpiry</td></tr>\n";
                    echo "\t<tr><td>Value</td><td>$data->vlexpiry</td></tr>\n";
                }
            }
        }
        echo "\t<tr><td>---</td><td>---</td></tr>\n";
    }
echo "</table>";

CodePudding user response:

That JSON has an irregular structure. Sure that is the actual data you receive? expiry is sometimes an array, sometimes an object. Very strange.

Take a look at this example to understand how to traverse it:

<?php
$json = <<<JSON
{"list":[{"expiry":[{"cdexpiry":"v130","vlexpiry":"33528.99"},{"cdexpiry":"v230","vlexpiry":"21648.39"},{"cdexpiry":"v150","vlexpiry":"185350.30"},{"cdexpiry":"v120","vlexpiry":"33904.03"},{"cdexpiry":"v175","vlexpiry":"47796.73"},{"cdexpiry":"v220","vlexpiry":"21258.62"},{"cdexpiry":"v170","vlexpiry":"261294.42"},{"cdexpiry":"v140","vlexpiry":"98363.25"},{"cdexpiry":"v110","vlexpiry":"30818.43"},{"cdexpiry":"v165","vlexpiry":"298457.07"},{"cdexpiry":"v240","vlexpiry":"13807.67"},{"cdexpiry":"v210","vlexpiry":"10761.00"},{"cdexpiry":"v160","vlexpiry":"321684.92"}],"mode":"0401","change":"N"},{"expiry":{"cdexpiry":"v210","vlexpiry":"3501.37"},"mode":"0204","change":"N"},{"expiry":{"cdexpiry":"v40","vlexpiry":"1091.46"},"mode":"1904","change":"N"},{"expiry":[{"cdexpiry":"v130","vlexpiry":"2084.08"},{"cdexpiry":"v260","vlexpiry":"28362.31"},{"cdexpiry":"v230","vlexpiry":"823.44"},{"cdexpiry":"v150","vlexpiry":"11738.63"},{"cdexpiry":"v120","vlexpiry":"2104.49"},{"cdexpiry":"v175","vlexpiry":"2678.84"},{"cdexpiry":"v220","vlexpiry":"823.44"},{"cdexpiry":"v170","vlexpiry":"17207.36"},{"cdexpiry":"v140","vlexpiry":"6131.73"},{"cdexpiry":"v110","vlexpiry":"1605.88"},{"cdexpiry":"v165","vlexpiry":"19333.84"},{"cdexpiry":"v210","vlexpiry":"3260.41"},{"cdexpiry":"v160","vlexpiry":"19818.10"}],"mode":"0213","change":"N"},{"expiry":{"cdexpiry":"v210","vlexpiry":"296.78"},"mode":"0101","change":"N"},{"expiry":[{"cdexpiry":"v245","vlexpiry":"14495.37"},{"cdexpiry":"v255","vlexpiry":"35462.84"},{"cdexpiry":"v250","vlexpiry":"15679.97"}],"mode":"0217","change":"N"}],"type":"8"}
JSON;

foreach (json_decode($json)->list as $listKey=>$listObj) {
    printf("[d] mode: %s / change: %s\n", $listKey, $listObj->mode, $listObj->change);
    if (is_array($listObj->expiry)) {
        foreach ($listObj->expiry as $expKey=>$obj) {
            printf("  [d] cdexpiry: %s / vlexpiry: %s\n", 
                   $expKey, $obj->cdexpiry, $obj->vlexpiry);
        }
    } else {
        $obj = $listObj->expiry;
        printf("  cdexpiry: %s / vlexpiry: %s\n", $obj->cdexpiry, $obj->vlexpiry);        
    }
}

The output is:

[000] mode: 0401 / change: N
  [000] cdexpiry: v130 / vlexpiry: 33528.99
  [001] cdexpiry: v230 / vlexpiry: 21648.39
  [002] cdexpiry: v150 / vlexpiry: 185350.30
  [003] cdexpiry: v120 / vlexpiry: 33904.03
  [004] cdexpiry: v175 / vlexpiry: 47796.73
  [005] cdexpiry: v220 / vlexpiry: 21258.62
  [006] cdexpiry: v170 / vlexpiry: 261294.42
  [007] cdexpiry: v140 / vlexpiry: 98363.25
  [008] cdexpiry: v110 / vlexpiry: 30818.43
  [009] cdexpiry: v165 / vlexpiry: 298457.07
  [010] cdexpiry: v240 / vlexpiry: 13807.67
  [011] cdexpiry: v210 / vlexpiry: 10761.00
  [012] cdexpiry: v160 / vlexpiry: 321684.92
[001] mode: 0204 / change: N
  cdexpiry: v210 / vlexpiry: 3501.37
[002] mode: 1904 / change: N
  cdexpiry: v40 / vlexpiry: 1091.46
[003] mode: 0213 / change: N
  [000] cdexpiry: v130 / vlexpiry: 2084.08
  [001] cdexpiry: v260 / vlexpiry: 28362.31
  [002] cdexpiry: v230 / vlexpiry: 823.44
  [003] cdexpiry: v150 / vlexpiry: 11738.63
  [004] cdexpiry: v120 / vlexpiry: 2104.49
  [005] cdexpiry: v175 / vlexpiry: 2678.84
  [006] cdexpiry: v220 / vlexpiry: 823.44
  [007] cdexpiry: v170 / vlexpiry: 17207.36
  [008] cdexpiry: v140 / vlexpiry: 6131.73
  [009] cdexpiry: v110 / vlexpiry: 1605.88
  [010] cdexpiry: v165 / vlexpiry: 19333.84
  [011] cdexpiry: v210 / vlexpiry: 3260.41
  [012] cdexpiry: v160 / vlexpiry: 19818.10
[004] mode: 0101 / change: N
  cdexpiry: v210 / vlexpiry: 296.78
[005] mode: 0217 / change: N
  [000] cdexpiry: v245 / vlexpiry: 14495.37
  [001] cdexpiry: v255 / vlexpiry: 35462.84
  [002] cdexpiry: v250 / vlexpiry: 15679.97

Considering that strange structure of the JSON data you receive I really would recommend to try to have that structure fixed insteead of trying to use that structure. The unexpected varying formatting inside the JSON data makes it unnecessarily complex to process. I fail to see a reason for that. objects inside an API response should always have a strict and uniform structure.

  • Related