Parse for a specific value in nested json using php - php

I know this question has been asked, but i'm at my wit's end and cannot figure this out.
I have a json file that looks like this:
{
"objects": [
{
"url": "http://whatever",
"name": "whatever"
},
{
"url": "http://anything",
"name": "anything"
}
] }
In my PHP file, I have this:
// Read JSON file
$json = require('blogtest.json');
//Decode JSON
$arr = json_decode($json,true);
// Loop through Object
if (is_array($arr) || is_object($arr))
{
foreach ($ar as $arr)
{
echo $ar["objects"]["name"] + "<br>";
}
}
and instead of printing the name values - it prints the entire json file. I've tried changing the filters, writing it different ways, and I just cannot get json to ever do what I need.
Is there any possible way to just get this to print out the two "name" values?!

Replace require with file_get_contents.
What require does is to include the file, not to return the contents of the file.
Then you can loop the items with
foreach($ar["objects"] as $item) {
// $item['name'];
}

Your foreach loop is wrong.
The foreach block should be written as:
foreach ($arr['objects'] as $ar) {
echo $ar["name"] . '<br />';
}
Also, use file_get_contents instead of require.

Related

Foreach PHP looping troubles

I'm having trouble decoding my json it seems only to decode one of the "geometry->coordinates" fields like only one polygon. It has something with # LINE 5 to do. How can i fix it will actual work.
i've built what i got now with help from here:
How to extract and access data from JSON with PHP?
# LINE 5
foreach($polygon->features[0]->geometry->coordinates as $coordinates)
# FULL CODE
<?php
$str = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[9.78281,54.923985],[9.80341,54.901586],[9.819803,54.901981],[9.83551,54.908396],[9.825897,54.91481],[9.822721,54.927142],[9.807186,54.927931],[9.792767,54.926797],[9.78281,54.923985]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[9.914474,54.930298],[9.901085,54.912343],[9.849243,54.912146],[9.846497,54.928917],[9.890785,54.946865],[9.930267,54.937399],[9.914474,54.930298]]]}}]}';
$polygon = json_decode($str);
foreach($polygon->features[0]->geometry->coordinates as $coordinates)
{
print_r($coordinates);
}
?>
You are only looping over the first (or zeroth) item by doing $polygon->features[0]. Instead, loop over those features, too:
foreach($polygon->features as $feature){
foreach($feature->geometry->coordinates as $coordinates)
{
print_r($coordinates);
}
}
Demo: https://3v4l.org/kk0uZ
<?php
$str = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[9.78281,54.923985],[9.80341,54.901586],[9.819803,54.901981],[9.83551,54.908396],[9.825897,54.91481],[9.822721,54.927142],[9.807186,54.927931],[9.792767,54.926797],[9.78281,54.923985]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[9.914474,54.930298],[9.901085,54.912343],[9.849243,54.912146],[9.846497,54.928917],[9.890785,54.946865],[9.930267,54.937399],[9.914474,54.930298]]]}}]}';
$polygon = json_decode($str);
foreach($polygon->features as $feature) {
foreach($feature->geometry->coordinates as $coordinates) {
print_r($coordinates);
}
}

fetching two type of json files with different beginning of structure

I'm processing json file with php with little difference in the beginning of the file ,my problem now is that i built two foreach loops and i am looking for a way to make it one loop.
{"code":0,"rid":"0","data":{"subid":"9174906486819979969","data":{"more":
{"code":0,"rid":"0","data":{"9174906486819979969":{"more":
Now I'm doing like that and it double the code for processing , the rest of the json file is all the same.
foreach($json['data']['data'])
{
}
foreach($json['data'])
{
}
What i need is one foreach loop instead of 2, is that possible?
You can check for the key and if present use it, if not then get the first key:
if(isset($json['data']['data'])) {
$data = $json['data']['data'];
} else {
$data = reset($json['data']); //or current()
}
Or shorter:
$data = $json['data']['data'] ?? reset($json['data']);
Then:
foreach($data as $values) {
//code
}
Another option would be to loop and check for an array, depending on the structure you have:
foreach($json['data'] as $values) {
if(is_array($values)) {
foreach($values as $v) {
//code
}
}

How to match a value in json file with PHP

I am saving data in JSON file for retrieving after redirect. If I check if the value matches in the json array, I always get false and something must be wrong, but I cannot figure it out. How can I the object with the specific SSL_SESSION_ID
Here's my json
[
{
"SSL_CLIENT_S_DN_CN": "John,Doe,12345678912",
"SSL_CLIENT_S_DN_G": "JOHN",
"SSL_CLIENT_S_DN_S": "DOE",
"SSL_CLIENT_VERIFY": "SUCCESS",
"SSL_SESSION_ID": "365cb4834f9d7b3d53a3c8b2eba55a49d5cac0112994fff95c690b9079d810af"
},
{
"SSL_CLIENT_S_DN_CN": "John,Doe,12345678912",
"SSL_CLIENT_S_DN_G": "JOHN",
"SSL_CLIENT_S_DN_S": "DOE",
"SSL_CLIENT_VERIFY": "SUCCESS",
"SSL_SESSION_ID": "e7bd2b6cd3db89e2d6fad5e810652f2ae087965e64b565ec8933b1a67120b0ac"
}
]
Here's my PHP script, which always returns It doesn't match
$sslData = Storage::disk('private')->get('ssl_login.json');
$decodedData = json_decode($sslData, true);
foreach ($decodedData as $key => $items) {
if ($items['SSL_SESSION_ID'] === $SSL_SESSION_ID) {
dd("It matches");
} else {
dd("It doesn't match");
}
}
Your script will always end after the first iteration, since you're using dd() regardless if it was a match or not and you will always get the "no-match"-message if the first iteration isn't a match.
You should iterate through all the items and then see if there was a match or not:
$match = null;
foreach ($decodedData as $key => $items) {
if ($items['SSL_SESSION_ID'] === $SSL_SESSION_ID) {
$match = $items;
// We found a match so let's break the loop
break;
}
}
if (!$match) {
dd('No match found');
}
dd('Match found');
That will also save the matching item in the $match variable if you need to use the data somehow.

Getting first object from a JSON file

How do I get access to the "thumburl" if I do not know the "pageid"?
{
"continue": {
"iistart": "2004-12-19T12:37:26Z",
"continue": "||"
},
"query": {
"pages": {
"30260": {
"pageid": 30260,
"ns": 6,
"title": "File:Japanese diet inside.jpg",
"imagerepository": "local",
"imageinfo": [
{
"thumburl": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e1/Japanese_diet_inside.jpg/130px-Japanese_diet_inside.jpg",
"thumbwidth": 130,
"thumbheight": 95,
"url": "https://upload.wikimedia.org/wikipedia/commons/e/e1/Japanese_diet_inside.jpg",
"descriptionurl": "https://commons.wikimedia.org/wiki/File:Japanese_diet_inside.jpg",
"descriptionshorturl": "https://commons.wikimedia.org/w/index.php?curid=30260"
}
]
}
}
}
}
With multiple objects in php I can do this imageinfo[0] but If I put $imageurl = $data->query->pages[0]->imageinfo[0]->thumburl; It is not working because it is an object not an array.
How can I do that?
You can call get_object_vars to get an associative array of the object properties, then get the first of these.
$props = array_values(get_object_vars($data->query->pages));
$imageurl = $props[0]->imageinfo[0]->thumburl;
You could use reset() to get the first element :
$data = json_decode($json) ;
$elem = reset($data->query->pages) ;
$imageurl = $elem->imageinfo[0]->thumburl ;
Another alternative is to decode as an array and re-index so it always starts at 0:
$result = array_values(json_decode($json, true)['query']['pages'])[0];
Then you can access $result['imageinfo']['thumburl'] or append it to the above.
You can loop through it, so you don't need array key like this:
$pages = (array) $data->query->pages;
foreach($pages as $page) {
$imageinfo = $page->imageinfo[0]->thumburl;
}
But this will get you only last from list of pages. So in case you know there are more pages, you need to store these thumburl in array. Or in case you are sure you want only first, just exit after first loop.

PHP - What is the best way to access a property of an object which is an array element

I have an object which is an array of JSON objects. Kinda Like this,
$object = [
{
"id":1,
"name":"blue",
"order":4
},
{
"id":2,
"name":"green",
"order":6
},
{
"id":3,
"name":"yellow",
"order":2
}
]
I wanted to access the properties in a simple way and a single line maybe like this,
Say if I wanted the "order" of the object with name "blue"
$blue_order = $object[something]->[name="blue"]->order;
Kinda mixed Jquery in this. But I hope you understand. Right now the best I've got is this,
for($i=0; $i<count($object); $i++){
if($object[$i]->name == "blue"){
$blue_order = $object[$i]->order;
}
}
This seems very inefficient though and I don't want to use a loop because the array is very large and looping through it will be very slow. So how do I do this?
I used a "for" loop instead of foreach because the array can be null. And also the order of the array elements will not always be the same.
So I can't do something like
$object[0]->order
<?php
$arr = array(
array('id'=>1,'name'=>'blue','order'=>4),
array('id'=>2,'name'=>'green','order'=>6),
array('id'=>3,'name'=>'yellow','order'=>2),
);
// $json is JSON version of the arrays in $arr
$json = json_encode($arr);
// show $json
echo $json . "\n";
// create arrays from JSON so it can be used in PHP easier
$obj = json_decode($json);
$color = 'blue';
$blue_order = array_filter($obj, function($i) use ($color) { return $i->name == $color; })[0]->order;
echo "Blue Order: " . $blue_order;
You may be able to use array_filter to help this become a one-liner. I included the json_decode and json_encode so I could have a complete example.
You could still use foreach but check if the array isn't empty first, like this:
if(!empty($object)){
foreach($object as $element){
if($element->name == "blue"){
$blue_order = $element->order;
}
}
}
Also, your code looks efficient to me, what I would probably add is a break after you find the value, like this:
if(!empty($object)){
foreach($object as $element){
if($element->name == "blue"){
$blue_order = $element->order;
break;
}
}
}
If your object has a lot of information and you're going to do a lot of searches, then you could do some pre-processing so it get easier to search, like this:
$object_by_name = array();
if(!empty($object)){
foreach($object as $element){
$object_by_name[$element->name] = $element;
}
}
Then, you could search it like this:
if(!empty($object_by_name['blue'])){
$blue_order = $object_by_name['blue']->order
}
Keep it simple.
You're writing way too much code.
$array_list = ($array_list)?:[];
$array_list = array_filter($array_list,function($var) {
return ($var->name=="blue");
});
$order = ($array_list)? $array_list[0]->order :'';

Categories