简体   繁体   中英

Basic JSON Decode foreach loop not working php

been going at this for quite some time and I'm puzzled as to why using foreach loops does not work but the other way I show does work.

My Code:

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "http://maps.googleapis.com/maps/api/geocode/json?address=1%20The%20Strand%20Wellard");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
  "Content-Type: application/json"
));

$response = curl_exec($ch);

$json = json_decode($response, true);

foreach ($json['results'] as $item) {
  foreach ($item['geometry'] as $item2) {
    foreach ($item2['location'] as $item3) {
      echo $item3['lat'];
    }
  }
  echo $item['geometry']['location']['lat'];
}

curl_close($ch);

JSON Data: https://pastebin.com/JU1wSpsD

Why doesn't echo $item3['lat']; work but echo $item['geometry']['location']['lat']; does work? If someone could help me understand why this is that would be great!

Just look at the json you are getting from the curl request, you are trying to iterate the geometry which not multidimensional.

Look in below code if geometry was like

"geometry": [{
        "location": {
          "lat": -32.2630411,
          "lng": 115.8164093
        }],

that can be iterate, but the format of you have received can be accessed directly like this.

"geometry": {
            "location": {
              "lat": -32.2630411,
              "lng": 115.8164093
            },
foreach ($json['results'] as $item) {

  echo $item['geometry']['location']['lat'];
  echo $item['geometry']['location']['lng'];
} 

Below is the json you getting from curl.

{
  "results": [
    {
      "address_components": [
        {
          "long_name": "1",
          "short_name": "1",
          "types": [
            "street_number"
          ]
        },
        {
          "long_name": "The Strand",
          "short_name": "The Strand",
          "types": [
            "route"
          ]
        },
        {
          "long_name": "Wellard",
          "short_name": "Wellard",
          "types": [
            "locality",
            "political"
          ]
        },
        {
          "long_name": "City of Kwinana",
          "short_name": "Kwinana",
          "types": [
            "administrative_area_level_2",
            "political"
          ]
        },
        {
          "long_name": "Western Australia",
          "short_name": "WA",
          "types": [
            "administrative_area_level_1",
            "political"
          ]
        },
        {
          "long_name": "Australia",
          "short_name": "AU",
          "types": [
            "country",
            "political"
          ]
        },
        {
          "long_name": "6170",
          "short_name": "6170",
          "types": [
            "postal_code"
          ]
        }
      ],
      "formatted_address": "1 The Strand, Wellard WA 6170, Australia",
      "geometry": {
        "location": {
          "lat": -32.2630411,
          "lng": 115.8164093
        },
        "location_type": "ROOFTOP",
        "viewport": {
          "northeast": {
            "lat": -32.2616921197085,
            "lng": 115.8177582802915
          },
          "southwest": {
            "lat": -32.2643900802915,
            "lng": 115.8150603197085
          }
        }
      },
      "place_id": "ChIJTTGvZi2FMioReYR3OgBb-p4",
      "plus_code": {
        "compound_code": "PRP8+QH Wellard, Western Australia, Australia",
        "global_code": "4PVQPRP8+QH"
      },
      "types": [
        "street_address"
      ]
    }
  ],
  "status": "OK"
}

$json['results'][0]['geometry'] in the JSON is an object, not an array. when you convert it you get an array with keys 'location', 'location_type' and 'viewport':

[geometry] => Array
      (
          [location] => Array
               (
                    [lat] => -32.2630411
                    [lng] => 115.8164093
                )
          [location_type] => ROOFTOP
          [viewport] => Array
              (
                   [northeast] => Array
                       (
                           [lat] => -32.261692119708
                           [lng] => 115.81775828029
                       )
                    [southwest] => Array
                       (
                           [lat] => -32.264390080291
                           [lng] => 115.81506031971
                       )
               )
        )

$item2 then becomes those values in turn, ie

Array
    (
         [lat] => -32.2630411
         [lng] => 115.8164093
    )

then

'ROOFTOP'

then

Array
    (
         [northeast] => Array
              (
                   [lat] => -32.261692119708
                   [lng] => 115.81775828029
               )
          [southwest] => Array
               (
                   [lat] => -32.264390080291
                   [lng] => 115.81506031971
               )
       )

As you can see, none of these arrays has a key 'location' so the foreach on $item2['location'] fails.

However you can directly access $json['results'][0]['geometry']['location']['lat'] or in your code $item['geometry']['location']['lat']

please first do var_dump:

echo '<pre style="direction:ltr">';
var_dump($json['results']);
die();

var_dump result is:

    array(1) {
  [0]=>
  array(6) {
    ["address_components"]=>
    array(7) {
      [0]=>
      array(3) {
        ["long_name"]=>
        string(1) "1"
        ["short_name"]=>
        string(1) "1"
        ["types"]=>
        array(1) {
          [0]=>
          string(13) "street_number"
        }
      }
      [1]=>
      array(3) {
        ["long_name"]=>
        string(10) "The Strand"
        ["short_name"]=>
        string(10) "The Strand"
        ["types"]=>
        array(1) {
          [0]=>
          string(5) "route"
        }
      }
      [2]=>
      array(3) {
        ["long_name"]=>
        string(7) "Wellard"
        ["short_name"]=>
        string(7) "Wellard"
        ["types"]=>
        array(2) {
          [0]=>
          string(8) "locality"
          [1]=>
          string(9) "political"
        }
      }
      [3]=>
      array(3) {
        ["long_name"]=>
        string(15) "City of Kwinana"
        ["short_name"]=>
        string(7) "Kwinana"
        ["types"]=>
        array(2) {
          [0]=>
          string(27) "administrative_area_level_2"
          [1]=>
          string(9) "political"
        }
      }
      [4]=>
      array(3) {
        ["long_name"]=>
        string(17) "Western Australia"
        ["short_name"]=>
        string(2) "WA"
        ["types"]=>
        array(2) {
          [0]=>
          string(27) "administrative_area_level_1"
          [1]=>
          string(9) "political"
        }
      }
      [5]=>
      array(3) {
        ["long_name"]=>
        string(9) "Australia"
        ["short_name"]=>
        string(2) "AU"
        ["types"]=>
        array(2) {
          [0]=>
          string(7) "country"
          [1]=>
          string(9) "political"
        }
      }
      [6]=>
      array(3) {
        ["long_name"]=>
        string(4) "6170"
        ["short_name"]=>
        string(4) "6170"
        ["types"]=>
        array(1) {
          [0]=>
          string(11) "postal_code"
        }
      }
    }
    ["formatted_address"]=>
    string(40) "1 The Strand, Wellard WA 6170, Australia"
    ["geometry"]=>
    array(3) {
      ["location"]=>
      array(2) {
        ["lat"]=>
        float(-32.2630411)
        ["lng"]=>
        float(115.8164093)
      }
      ["location_type"]=>
      string(7) "ROOFTOP"
      ["viewport"]=>
      array(2) {
        ["northeast"]=>
        array(2) {
          ["lat"]=>
          float(-32.2616921197085)
          ["lng"]=>
          float(115.8177582802915)
        }
        ["southwest"]=>
        array(2) {
          ["lat"]=>
          float(-32.2643900802915)
          ["lng"]=>
          float(115.8150603197085)
        }
      }
    }
    ["place_id"]=>
    string(27) "ChIJTTGvZi2FMioReYR3OgBb-p4"
    ["plus_code"]=>
    array(2) {
      ["compound_code"]=>
      string(45) "PRP8+QH Wellard, Western Australia, Australia"
      ["global_code"]=>
      string(11) "4PVQPRP8+QH"
    }
    ["types"]=>
    array(1) {
      [0]=>
      string(14) "street_address"
    }
  }
}

you must get index 0 from result:

    echo '<pre style="direction:ltr">';
    var_dump($json['results'][0]['geometry']   ['location']['lat']);
    die();

result is: float(-32.2630411)

Try this, it's working here Your code doesn't work because your first foreach loop will loop through one time as $json['results'] has only one index 0 and the second foreach loop will loop through three times as $item['geometry'] has three indexes (location,location_type,viewport). in this second foreach loop your $item2 variable will contain the value of each indexs from (location,location_type,viewport) that means you will get the 'lat' index in this $item2 variable. You need not to run then third foreach loop :)

    <?php 
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "http://maps.googleapis.com/maps/api/geocode/json?address=1%20The%20Strand%20Wellard");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
  "Content-Type: application/json"
));

$response = curl_exec($ch);

$json = json_decode($response, true);


foreach ($json['results'] as $item) {

  foreach ($item['geometry'] as $key=>$item2) {

   if($key == 'location')
    echo $item2['lat'];

    }

}

curl_close($ch);

?>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM