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
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);
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"
}
}
}
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 [▶]
]
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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();
Been trying $match[0] which not working
Not sure where the 41 is coming from?
$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 ▶}
}
]
}
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:
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);
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";
}
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'};
}
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'};
}
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.
Over my head obviously but seeing a light at the tunnel with all your help.
ASKER
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){
.....
}