Link to home
Start Free TrialLog in
Avatar of tjyoung
tjyoung

asked on

How to parse json to extract only what I need (Laravel, PHP, guzzle, Rest API)

Hi,
So... I'm retrieving vehicle images from a rest service.
It returns quite a number of possible images and I'm only after a certain one.
So my question would be:
How do I go through the result and extract just what I require to display an image.

My (shortened) response looks like below (I'm only interested in the 'colorized images' a little ways down in the file) and as an example I'm looking to get the image that matches:
primaryColorOptionCode - PBJ
shotCode - 01
width: 1280

{
   "view":[
      {
         "@width":"320",
         "@height":"240",
         "@shotCode":"07",
         "@backgroundDescription":"White",
         "@href":"http://media.chromedata.com/MediaGallery/media/Mjc0ODgyXk1lZGlhIEdhbGxlcnk/5zalboWvMJfiO8memsH19dndmAek1JSv6veHqtcd9-hMO4PAO3xwZa7RIeSA2iqayIk7XPB183yKmimK_3GFSgWF25TrWriygD-_AL3sncFE6i7EWXaNzhd4FGV8Euh4xSo7mEENJFg/2021JES040022_320_07.jpg",
         "@type":"resource",
         "flags":{
            "carryOver":"Y",
            "exactMatch":"N",
            "oemTemp":"N"
         }
      },
      {
         "@width":"2100",
         "@height":"1575",
         "@shotCode":"11",
         "@backgroundDescription":"Transparent",
         "@href":"http://media.chromedata.com/MediaGallery/media/Mjc0ODgyXk1lZGlhIEdhbGxlcnk/5zalboWvMJfiO8memsH19dndmAek1JSv6veHqtcd9-iLHw8LnwGFNvt8alURtJ4Oc3JDs-tEzdLSYcjipUFzV-Zb2wG0e2VsCbw-DrhSdF9Wk8lzxZPiyXcZyHXQOyb7ZZbnoZe9mcdGNmlswUiQ1_Rp-hGRvTsF/2021JES040023_2100_11.png",
         "@type":"resource",
         "flags":{
            "carryOver":"Y",
            "exactMatch":"N",
            "oemTemp":"N"
         }
      },
      {
         "@width":"320",
         "@height":"240",
         "@shotCode":"44",
         "@backgroundDescription":"White",
         "@href":"http://media.chromedata.com/MediaGallery/media/Mjc0ODgyXk1lZGlhIEdhbGxlcnk/5zalboWvMJfiO8memsH19dndmAek1JSv6veHqtcd9-glE_mzMMtnlthSpd2HrFNavB2UshXp406YrWnED59UkaTJaub3Kzkg90UgLqaIVXtAun0ihR88sRaU94imJG0qonf8XCaf6W8/2021JES040033_320_44.jpg",
         "@type":"resource",
         "flags":{
            "carryOver":"Y",
            "exactMatch":"N",
            "oemTemp":"N"
         }
      }
   ],
   "colorized":[
      {
         "@primaryColorOptionCode":"PT6",
         "@secondaryColorOptionCode":"",
         "@primaryRGBHexCode":"7E7267",
         "@secondaryRGBHexCode":"",
         "@width":"1280",
         "@height":"960",
         "@shotCode":"01",
         "@backgroundDescription":"White",
         "@href":"http://media.chromedata.com/MediaGallery/media/Mjc0ODgyXk1lZGlhIEdhbGxlcnk/4QRlU77m-R0m0i5MmJdZ91qENP8mrd3gZwyQlUjYAERJglsXT0rS7Gc4fwcl1zKr0Ip5Z4rDXebna7BhxHqPUzZqcmGnlGzYiCWVuC_BGB2pTOHRx6TAp1P5ucuIexaRwyfBCxLtQ9QekK3WQuYS1An9fXu3EkWdBmSiz28M1io6yKhN76TO8w/cc_2021JES040029_01_1280_PT6.jpg",
         "@type":"resource",
         "flags":{
            "carryOver":"Y",
            "exactMatch":"N",
            "oemTemp":"N"
         }
      },
      {
         "@primaryColorOptionCode":"PF2",
         "@secondaryColorOptionCode":"",
         "@primaryRGBHexCode":"DA3421",
         "@secondaryRGBHexCode":"",
         "@width":"1280",
         "@height":"960",
         "@shotCode":"01",
         "@backgroundDescription":"White",
         "@href":"http://media.chromedata.com/MediaGallery/media/Mjc0ODgyXk1lZGlhIEdhbGxlcnk/4QRlU77m-R0m0i5MmJdZ91qENP8mrd3gZwyQlUjYAERJglsXT0rS7MQV1Iwi5cqA-jlTTGzFU3UYKuTr6YFHiMbVLVSibTUJJlOU0-S0In_I_n-TPP911cUCc68J0biTOk2GnJqjr6yk8YCMwNqCRc_O9TV562AR0SSP3ndtAnkMKcvXCIBrow/cc_2021JES040022_01_1280_PF2.jpg",
         "@type":"resource",
         "flags":{
            "carryOver":"Y",
            "exactMatch":"N",
            "oemTemp":"N"
         }
      },
      {
         "@primaryColorOptionCode":"PBJ",
         "@secondaryColorOptionCode":"",
         "@primaryRGBHexCode":"0A4B71",
         "@secondaryRGBHexCode":"",
         "@width":"1280",
         "@height":"960",
         "@shotCode":"01",
         "@backgroundDescription":"White",
         "@href":"http://media.chromedata.com/MediaGallery/media/Mjc0ODgyXk1lZGlhIEdhbGxlcnk/4QRlU77m-R0m0i5MmJdZ91qENP8mrd3gZwyQlUjYAERJglsXT0rS7JD4oZsX0y7q87n2LxPIxIq-neWckXBVALRr5ITZI9S75mkxja09DcTo6fXXpcrMx6MwFeUVVDpouE4acqDenLExY5QYlhacoLITLWyB_GxpIxKixDag1OCusmFc_oRpxA/cc_2021JES040020_01_1280_PBJ.jpg",
         "@type":"resource",
         "flags":{
            "carryOver":"Y",
            "exactMatch":"N",
            "oemTemp":"N"
         }
      },
      {
         "@primaryColorOptionCode":"PSC",
         "@secondaryColorOptionCode":"",
         "@primaryRGBHexCode":"838587",
         "@secondaryRGBHexCode":"",
         "@width":"640",
         "@height":"480",
         "@shotCode":"01",
         "@backgroundDescription":"White",
         "@href":"http://media.chromedata.com/MediaGallery/media/Mjc0ODgyXk1lZGlhIEdhbGxlcnk/4QRlU77m-R0m0i5MmJdZ91qENP8mrd3gZwyQlUjYAERJglsXT0rS7C3nO6K5OcyNenDumnvK1gziLanw3J1DBUtl_QYmNDirU2YSzBV5QfiM07ZNnpyx42RooUX-trK1-cQRna4TNUuBvkRK5XcOvmntNFFGkIAg-HGL3koYmqAIcOCyKEZWsQ/cc_2021JES040017_01_640_PSC.jpg",
         "@type":"resource",
         "flags":{
            "carryOver":"Y",
            "exactMatch":"N",
            "oemTemp":"N"
         }
     }
   ],
   "stock":{
      "@width":"400",
      "@height":"200",
      "@href":"http://media.chromedata.com/MediaGallery/media/Mjc0ODgyXk1lZGlhIEdhbGxlcnk/GNd_ulFNA8wZtnAHSi29W8RZ4ggBc0FVBBjh_R7VizwR3TNfdpc3RdTdi7G0p5m3FdjcyeMxiLsGK9JKngUjpifideAslXPd/32445.jpg",
      "@type":"resource",
      "flags":{
         "carryOver":"N",
         "exactMatch":"N",
         "oemTemp":"Y"
      }
   }
}

Open in new window

Any idea how to get at that image?
If it helps, I'm doing the request like this:

$client = new Client();
    $res = $client->request('GET','http://media.chromedata.com//MediaGallery/service/style/417106.json', [
    'auth' =>  ['1234567', '7b8e36335a9a777a']
    ]);

    $result = $res->getBody();

Am also looking at converting to an array possibly?
Tried this with the result and got below:
$result = json_decode( $res->getBody(), true );
    dd($result);

array:3 [
  "view" => array:120 []
  "colorized" => array:216 []
  "stock" => array:5 []
]

Open in new window



ASKER CERTIFIED SOLUTION
Avatar of Chris Stanyon
Chris Stanyon
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of tjyoung
tjyoung

ASKER

HI, this is working and getting the expected return. Thank you very much as always!
Can you chain multiple 'where' in order to filter it down further? In my case I need the PBJ and also shot code and width to get the correct one.

Lastly: to ensure you got the expected return, what is the best way to check?
if($match){
.....
}
Avatar of tjyoung

ASKER

I'm doing multiple where's and getting this for a vehicle as an example:

$match      = $colorized
                        ->where('@primaryColorOptionCode',$vehicle->ColorCode)
                        ->where('@shotCode','03')
                        ->where('@width','640')
                        ->where('@backgroundDescription','White');
                        dd($match);
                        exit();

Illuminate\Support\Collection {#1361 ▼
  #items: array:1 [
    41 => {#1007 ▼
      +"@primaryColorOptionCode": "B3"
      +"@secondaryColorOptionCode": ""
      +"@primaryRGBHexCode": "1F45A3"
      +"@secondaryRGBHexCode": ""
      +"@width": "640"
      +"@height": "480"
      +"@shotCode": "03"
      +"@backgroundDescription": "White"
      +"@href": "http://media.chromedata.com/MediaGallery/media/Mjc0ODgyXk1lZGlhIEdhbGxlcnk/QCU7dSKDx539iNHvsOpz2p1TE_DQKliwms_ZHijcerYUbDvYXAHnaycbJIHMbF2y0ycXn7eoSSg5wsYa9JTWe"
      +"@type": "resource"
      +"flags": {#1008 ▶}
    }
  ]
}

Open in new window

Any idea how to get the href out of that?
Been trying $match[0] which not working
Not sure where the 41 is coming from?
Hey there,

The where() and firstWhere() methods only take one key/value pair. If you want to search on more than one, you'll want to use the filter() method instead:

$json = json_decode($data);
$colorized = collect($json->colorized); // create a collection from the colorized property

$matches = $colorized->filter(function($item, $key) {
    return $item->{'@primaryColorOptionCode'} == 'PBJ'
        && $item->{'@shotCode'} == '01'
        && $item->{'@width'} == '1280';
});

dd($matches);

Open in new window

This method will return a Collection containing all the items that match the filter. To access the items, you'd need to loop over them (even if there's only one). You can check the results by counting the number of items in the collection:

if ($matches->count()) {
    echo "We have records";
    foreach ($matches as $match) {
        var_dump($match);
    }
} else {
    echo "No records";
}

Open in new window

Avatar of tjyoung

ASKER

I apologize for the extra question with this. Your initial answer worked great. I just wasn't sure about starting a new. Trying this now. Using just the firstWhere worked great and was very cool to see it populate with images. Thanks very much for everything.
OK - when you use where(), the result will be a Collection, so it contain the matches, even if there's only one. If there' likely to be more than one, then you'd loop over them. If you know there's only gonna be one, then call the first() method on the results. THis would give you single item as an object (stdClass) so you can access the props as normal:

$match = $colorized
    ->where('@primaryColorOptionCode',$vehicle->ColorCode)
    ->where('@shotCode','03')
    ->where('@width','640')
    ->where('@backgroundDescription','White')
    ->first();

if ($match) {
    echo $match->{'@href'};
}

Open in new window

To loop over:

$matches = $colorized
    ->where('@primaryColorOptionCode',$vehicle->ColorCode)
    ->where('@shotCode','03')
    ->where('@width','640')
    ->where('@backgroundDescription','White');

foreach ($matches as $match) {
    echo $match->{'@href'};
}

Open in new window

Avatar of tjyoung

ASKER

Thats amazing. Thanks again. Got enough to work with now to figure this thing out.
Over my head obviously but seeing a light at the tunnel with all your help.