1

All I want is the value long_name for the listing with type postal_code. It's on a different array ID on each address variation otherwise I would have just used semething like this:

$jsonobj->results[0]->address_components[2]->long_name;

That won't work though ;(

This is the code, from the Google GEO location API

{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "2565",
               "short_name" : "2565",
               "types" : [ "postal_code", "postal_code_prefix" ]
            },
            {
               "long_name" : "Den Haag",
               "short_name" : "Den Haag",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "Den Haag",
               "short_name" : "Den Haag",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "Zuid-Holland",
               "short_name" : "ZH",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "Nederland",
               "short_name" : "NL",
               "types" : [ "country", "political" ]
            }
         ],
         "formatted_address" : "2565 Den Haag, Nederland",
         "geometry" : {
            "bounds" : {
...

So, in short, how can i get the "long_name" value for "types == postal_code" (maybe with in_array(postal_code, $types)?).

Answer already given but wanted to post my version of the function here as well:

$city          = getAddressDetail($jsonobj, 'locality');
$zipcode       = getAddressDetail($jsonobj, 'postal_code');

function getAddressDetail($jsonobj, $attr){
    // Loop over each result
    foreach ($jsonobj->results as $result) {
        // Loop over each address_component of a given result
        foreach ($result->address_components as $component) {
            // Check for 'postal_code' in the types array
            if (in_array($attr, $component->types, true)) {
                // Extract the 'long_name'
                return $component->long_name;
            }
        }
    }
}
8
  • That won't work though - why not? are you getting an error? Commented Jul 31, 2018 at 15:00
  • Did you use json_decode($jsonobj, true) to turn the data from json into an array? Commented Jul 31, 2018 at 15:01
  • No Dirk, i use objects. I like that better. $jsonobj = json_decode($curl_response); Commented Jul 31, 2018 at 15:02
  • @SeanBright that works for the given value, but like it wrote, for each address the order is different, Google API does return different results for each address (like with ZIP, No ZIP, city only etc.). The sample above would return the City just fine, but next time it may return the zipcde, or house number or else. Commented Jul 31, 2018 at 15:05
  • So then I guess you just want to use a foreach loop that loops through $jsonobj->results[0]->address_components and for each value it will check if types contains the value postal_code. If it does then you take the long_name value from that element and return it. Commented Jul 31, 2018 at 15:08

1 Answer 1

1

You just need to nest a few foreach loops and then use in_array():

<?php

// Loop over each result
foreach ($jsonobj->results as $result) {
    // Loop over each address_component of a given result
    foreach ($result->address_components as $component) {
        // Check for 'postal_code' in the types array
        if (in_array('postal_code', $component->types, true)) {
            // Extract the 'long_name'
            echo $component->long_name . "\n";
        }
    }
}

If you want to make the search more generic you could extract into a function:

<?php

function find_by_type($obj, $type) {
    $res = [];

    foreach ($obj->results as $result) {
        foreach ($result->address_components as $component) {
            if (in_array($type, $component->types, true)) {
                $res[] = $component->long_name;
            }
        }
    }

    return $res;
}

$res = find_by_type($jsonobj, 'postal_code');

var_dump($res);

And if you want to really fancy, pass in a callable that will extract the field that you want:

function find_by_type($obj, $type, $extractor) {
    $res = [];

    foreach ($obj->results as $result) {
        foreach ($result->address_components as $component) {
            if (in_array($type, $component->types, true)) {
                $res[] = $extractor($component);
            }
        }
    }

    return $res;
}

$res = find_by_type($jsonobj, 'postal_code', function($c) {
    return $c->short_name;
});

var_dump($res);
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks buddy. One can always rely on the men of SO with over 50k rep scores :-) It works well, I'll study it better since it always looks so simple when the result is there, whereas I have been trying all day long haha.
Haha, just went back here to post my new solution, only to find you have edited your answer and it sort of matches my findings:-). I have made it into a function as well so i can get any resulty back easily now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.