Iterate over JSON file using PHP [duplicate] - php

This question already has an answer here:
How to extract and access data from JSON with PHP?
(1 answer)
Closed 5 years ago.
I have a JSON file containing a list of universities around the world. I want to get only specific universities where a field in the array matches what I need to select. The problem I face is that each university has it's own ID number which makes me unable to figure out how to iterate over the Array. The JSON file can be found on this GitHub repo.
The code that makes me convert the JSON file to an array:
<?php
$json = file_get_contents('universities_list.json');
$universityArray = json_decode($json, true);
print_r($universityArray);
?>
And a sample of what I get is:
[2942] => Array
(
[alpha_two_code] => EG
[country] => Egypt
[domain] => aast.edu
[name] => Arab Academy for Science & Technology
[web_page] => http://www.aast.edu/
)
[2943] => Array
(
[alpha_two_code] => EG
[country] => Egypt
[domain] => akhbaracademy.edu.eg
[name] => Akhbar El Yom Academy
[web_page] => http://www.akhbaracademy.edu.eg/
)
What is the best or appropriate way to print out only the universities with alpha_two_code == 'EG' or == 'Egypt' for example?
I read the documentation on foreach loop and the examples as well. But still can't get the logic to get what I mentioned above.

Check this return only a specific country
<?php
$json = file_get_contents('university.json');
$universityArray = json_decode($json, true);
universities= array()
for($i=0; $i< count($universityArray); $i++)
{
if($universityArray[$i]["country"] == "Morocco")
universitises[] = $universityArray[$i];
}
var_dump($universitises);
?>

You can use alpha_two_code as index.
$indexed = [];
foreach($universityArray as $university){
$index = $university['alpha_two_code'];
if(!isset($indexed[$index])){
$indexed[$index] = [];
}
$indexed[$index][] = $university;
}
Now you will have universities seperated by alpha_two_code which you can directly access.
print_r($indexed['EG']);
Now as per the best and appropriate part, you may want to cache $indexed. You can create a directory for universities and save JSON encoded $indexed there.

You need to read the manual.
Try this:
$names = array();
foreach($universityArray as $u) {
if($u['alpha_two_code'] == 'EG' || $u['country'] == 'Egypt'){
$names[] = $u['name'];
}
}
print_r($names);

you can use the array_filter http://php.net/manual/en/function.array-filter.php function here with a callback. You can then use array_column http://php.net/manual/en/function.array-column.phpto grab just the 'name' column.
$json = file_get_contents('https://github.com/Hipo/university-domains-list/blob/master/world_universities_and_domains.json');
$universityArray = json_decode($json, true);
$filterBy = 'EG';
$newArray = array_filter($universityArray, function ($var) use ($filterBy) {
return ($var['alpha_two_code'] == $filterBy);
});
print_r($newArray);
$names = array_column($newArray, 'name');
print_r($names);

Related

PHP - Merge append multiple json arrays

I need to merge/join multiple json string that contains arrays (which also need to be merged) but I don't know what is the best way to achieve this :
Initial array of json strings (called $rrDatas in my example below):
Array
(
[0] => {"asset":[1],"person":[1]}
[1] => {"asset":[2]}
)
Expected result :
{"asset":[1,2],"person":[1]}
The main difficulty is that the number of arrays is undefined (my example is made with 2 arrays but it could be 3,4 etc.). The second difficulty is that there can be multiple properties (like "asset", "person" etc. however always arrays). These possible properties are known but are many so it would be better if the algorithm is dynamic.
What I am able to do at the moment :
$mergedAssets['asset'] = [];
foreach ($rrDatas as $rrData)
{
$rrDataJson = \GuzzleHttp\json_decode($rrData, true);
$mergedAssets['asset'] = array_merge($mergedAssets['asset'],$rrDataJson['asset']);
}
$result = \GuzzleHttp\json_encode($mergedAssets, true);
Result :
{"asset":[1,2]}
This works well but this is not dynamic, should I duplicate this part for each possible properties (i.e. "person", etc.) ?
Thanks,
Guillaume
Edit : Brett Gregson's and krylov123's answers below helped me build my own solution which is a mix between both suggestion:
$mergedJson = [];
foreach ($rrDatas as $rrData)
{
$rrDataJson = \GuzzleHttp\json_decode($rrData, true);
foreach(array_keys($rrDataJson) as $property)
{
$mergedJson[$property] = array_merge($mergedJson[$property] ?? [], $rrDataJson[$property]);
}
}
return \GuzzleHttp\json_encode($mergedJson, true);
Find below a better example :
$rrDatas = Array (
[0] => {"asset":[1,2],"person":[1],"passive":[1]}
[1] => {"asset":[3],"charge":[1],"passive":[2]}
)
Which must result in :
{"asset":[1,2,3],"person":[1],"passive":[1,2],"charge":[1]}
Edit 2 : I have just tried Progrock's solution and it seems to work perfectly as well : https://3v4l.org/7hSqi
You can use something like:
$output = []; // Prepare empty output
foreach($rrDatas as $inner){
foreach($inner as $key => $value){
$output[$key][] = $value;
}
}
echo json_encode($output); // {"asset":[1,2],"person":[1]}
Which should give you the desired output. This should work regardless of the keys within the individual arrays and even with empty arrays.
Working example here
Another example with more arrays and more keys and empty arrays
<?php
$array =
[
'{"asset":[1],"person":[1]}',
'{"asset":[2]}',
];
$array = array_map(function($v) { return json_decode($v, true);}, $array);
$merged = array_merge_recursive(...$array);
print json_encode($merged);
Output:
{"asset":[1,2],"person":[1]}
You need to use foreach ($array as $key => $value) iteration, to be able to dynamicaly use keys of your json array (e.g. "asset" and "person").
Solution:
$mergedAssets['asset'] = [];
foreach ($rrDatas as $key => $value)
{
$rrDataJson = \GuzzleHttp\json_decode($value, true);
$mergedAssets[$key] = array_merge($mergedAssets[$key],$rrDataJson[$key]);
}
$result = \GuzzleHttp\json_encode($mergedAssets, true);

How to make key value by explode and arrange matching key values into one key?

I am recently facing a practical problem.I am working with ajax form submission and there has been some checkboxes.I need all checkboxes with same name as key value pair.Suppose there is 4 checkboxes having name attribute =checks so i want something like $arr['checks'] = array(value1, value2, ...)
So i am getting my ajax $_POST code as suppose like: name=alex&checks=code1&checks=code2&checks=code3
I am using below code to make into an array
public function smdv_process_option_data(){
$dataarray = array();
$newdataarray = array();
$new = array();
$notices = array();
$data = $_POST['options']; // data received by ajax
$dataarray = explode('&', $data);
foreach ($dataarray as $key => $value) {
$i = explode('=', $value);
$j = 1;
if(array_key_exists($i[0], $newdataarray)){
if( !is_array($newdataarray[$i[0]]) ){
array_push($new, $newdataarray[$i[0]]);
}else{
array_push($new, $i[1]);
}
$newdataarray[$i[0]] = $new;
}else{
$newdataarray[$i[0]] = $i[1];
}
}
die($newdataarray);
}
Here i want $newdataarray as like below
array(
'name' => 'alex',
'checks => array(code1, code2, code3),
)
But any how I am missing 2nd value from checks key array.
As I see it you only need to do two explode syntaxes.
The first on is to get the name and here I explode on & and then on name= in order to isolate the name in the string.
The checks is an explode of &checks= if you omit the first item with array_slice.
$str = 'name=alex&checks=code1&checks=code2&checks=code3';
$name = explode("name=", explode("&", $str)[0])[1];
// alex
$checks = array_slice(explode("&checks=", $str), 1);
// ["code1","code2","code3"]
https://3v4l.org/TefuG
So i am getting my ajax $_POST code as suppose like: name=alex&checks=code1&checks=code2&checks=code3
Use parse_str instead.
https://php.net/manual/en/function.parse-str.php
parse_str ( string $encoded_string [, array &$result ] ) : void
Parses encoded_string as if it were the query string passed via a URL and sets variables in the current scope (or in the array if result is provided).
$s = 'name=alex&checks=code1&checks=code2&checks=code3';
parse_str($s, $r);
print_r($r);
Output
Array
(
[name] => alex
[checks] => code3
)
You may think this is wrong because there is only one checks but technically the string is incorrect.
Sandbox
You shouldn't have to post process this data if it's sent correctly, as that is not included in the question, I can only make assumptions about it's origin.
If your manually creating it, I would suggest using serialize() on the form element for the data for AJAX. Post processing this is just a band-aid and adds unnecessary complexity.
If it's from a source outside your control, you'll have to parse it manually (as you attempted).
For example the correct way that string is encoded is this:
name=alex&checks[]=code1&checks[]=code2&checks[]=code3
Which when used with the above code produces the desired output.
Array
(
[name] => alex
[checks] => Array
(
[0] => code1
[1] => code2
[2] => code3
)
)
So is the problem here, or in the way it's constructed...
UPDATE
I felt obligated to give you the manual parsing option:
$str = 'name=alex&checks=code1&checks=code2&checks=code3';
$res = [];
foreach(explode('&',$str) as $value){
//PHP 7 array destructuring
[$key,$value] = explode('=', $value);
//PHP 5.x list()
//list($key,$value) = explode('=', $value);
if(isset($res[$key])){
if(!is_array($res[$key])){
//convert single values to array
$res[$key] = [$res[$key]];
}
$res[$key][] = $value;
}else{
$res[$key] = $value;
}
}
print_r($res);
Sandbox
The above code is not specific to your keys, which is a good thing. And should handle any string formatted this way. If you do have the proper array format mixed in with this format you can add a bit of additional code to handle that, but it can become quite a challenge to handle all the use cases of key[] For example these are all valid:
key[]=value&key[]=value //[key => [value,value]]
key[foo]=value&key[bar]=value //[key => [foo=>value,bar=>value]]
key[foo][]=value&key[bar][]=value&key[bar][]=value //[key => [foo=>[value]], [bar=>[value,value]]]
As you can see that can get out of hand real quick, so I hesitate to try to accommodate that if you don't need it.
Cheers!

PHP - get value from JSON

Before i decode my JSON i get this result:
{
"1":[{"membership_id":1,"group_id":1,"user_id":1},
"2":[{"membership_id":3,"group_id":1,"user_id":2}
}
How would i specify that i want to select the one who has 'user_id' == 2 and return membership_id value?
My attempt, but i get undefined value 'user_id':
$myjson = json_decode($s_o, true);
foreach ($myjson as $key => $value){
if($value['user_id'] == $cid){
$mid = $value['membership_id'];
}
}
echo $mid;
Basically i guess i would first have to select the right object and go through it with the foreach, but here i got a bit lost in the situation.
Use Array-Functions:
$json = '{
"1":[{"membership_id":1,"group_id":1,"user_id":1}],
"2":[{"membership_id":3,"group_id":1,"user_id":2}]
}';
$array = json_decode($json, true);
$searchUserID = 2;
$filteredArray = array_filter($array, function($elem) use ($searchUserID){
return $searchUserID == $elem[0]['user_id'];
});
$mid = array_column(array_shift($filteredArray), 'membership_id')[0];
echo "Membership-ID: ".$mid;
array_filter uses a callback function that iterates over every element of the array. If the callback function returns true, that element is assigned to $filteredArray. No need for a foreach loop that way.
But the return value is the whole array element:
Array
(
[2] => Array
(
[0] => Array
(
[membership_id] => 3
[group_id] => 1
[user_id] => 2
)
)
)
So you have to extract your membership_id.
Read the following line from inside out.
First, we fetch the first entry of the array with array_shift (since we have only one entry, this will be our desired entry).
Array
(
[0] => Array
(
[membership_id] => 3
[group_id] => 1
[user_id] => 2
)
)
We pass this array on to array_column to find the entry in the encapsulated array with the column name membership_id. Since array_column again returns an array,
Array
(
[0] => 3
)
we get the (one and only) entry by adding [0] to the end of this command.
Since the last part is a little complicated, here's a torn apart version of it:
$firstEntryOfFilteredArray = array_shift($filteredArray);
$arrayWithValueOfColumnMembershipID = array_column($firstEntryOfFilteredArray, 'membership_id');
$membership_id = $arryWithValueOfColumnMembershipID[0];
These three lines are concatenated into this:
$mid = array_column(array_shift($filteredArray), 'membership_id')[0];
here's a working example: http://sandbox.onlinephpfunctions.com/code/8fe6ede71ca1e09dc68b2f3bec51743b27bf5303
I'm assuming the JSON actually looks like:
{
"1":[{"membership_id":1,"group_id":1,"user_id":1}],
"2":[{"membership_id":3,"group_id":1,"user_id":2}]
}
Each element of the object is an array for some reason. So you need to index it with $value[0] to access the object contained inside it.
$myjson = json_decode($s_o, true);
foreach ($myjson as $key => $value){
if($value[0]['user_id'] == $cid){
$mid = $value[0]['membership_id'];
break;
}
}
echo $mid;
If the arrays can contain multiple elements, you'll need nested loops.
$myjson = json_decode($s_o, true);
foreach ($myjson as $key => $value){
foreach ($value as $object) {
if($object['user_id'] == $cid){
$mid = $object['membership_id'];
break 2;
}
}
}
echo $mid;
This is a bit speculative, but I think the data is indexed by user ID. If that's the case, it makes the lookup much simpler.
After decoding with $myjson = json_decode($s_o, true);
Just find the record by ID and get the membership_id from the matching row.
$membership_id = reset($myjson['2'])['membership_id'];`
You should probably verify that that ID exists, so maybe something like:
$membership_id = isset($myjson['2']) ? reset($myjson['2'])['membership_id'] : null;
If I'm wrong and the fact that the row numbers match the user_id is just a coincidence, then never mind :)

New array from multidimensional array - url parsing

I have the following URL: myexample.com/?city=Miami
and a large array (23k)
$e = $_GET["city"];
$myArray = array
(
array ("Miami","Florida"),
array ("Key West","Florida"),
array ("NOLA", "Luisiana"),
array ("Baton Rouge","Luisiana")
);
I'm looking for a solution to dynamically create a new array of cities that matches the state of the city in the URL, and echo all the cities from that state.
In other words:
if myexample.com/?city=NOLA, I would like to echo "Baton Rouge" and "NOLA" (from Luisiana)
if myexample.com/?city=Miami, echo "Key West" and "Miami" (from Florida)
etc.
There are quite a few similar questions answered already (here, here, but looping is not one of strengths (beginner).
Thank you.
EDIT1:
$resArray = array();
foreach($myArray as $arr) {
if(in_array($e, $arr))
$resArray[] = $arr;
}
print_r($resArray);
Result: Array ( [0] => Array ( [0] => Miami [1] => Florida ) )
First of all I would restructure your myArray in something like the following:
$stateAndCities = [
"Florida" => ["Miami","Key West"],
"Luisiana" => ["NOLA", "Baton Rouge"]
];
after that you can better handle the input and give an easier output
$city = $_GET["city"];
$resultCities = [];
$resultState = "";
// Loop over all states with their cities
foreach($stateAndCities as $state => $cities) {
if(in_array($city, $cities)){ // if the given $city is in the $cities?
$resultCities = $cities;
$resultState = $state;
break;
}
}
if(!empty($resultState) && !empty($resultCities)){ // ensure that the city was found in any state
echo $resultState;
print_r($resultCities);
}
(the code is not tested!)
Manual:
http://php.net/in_array
http://php.net/empty

PHP - How to get the value of json api using Php? [duplicate]

This question already has an answer here:
How to extract and access data from JSON with PHP?
(1 answer)
Closed 3 years ago.
I have a question regarding on json.. I tried to get an api from other site and downloaded it as json file..I've already decoded this file using this code below..
$str = file_get_contents('../trelloApi.json');
$json = json_decode($str, true);
echo '<pre>' . print_r($json, true) . '</pre>';
From this image attached, how do I get or print the value of the [list] => Array, [board] => Array and [card] => Array?
Please help me :(
Looks like that the api return a array of arrays, then use foreach to iterate through the json_decode.
foreach ($json as $ticket) {
// if your $ticket['data'] is a StdClass, force to be array
$ticket['data'] = (array)$ticket['data'];
// now you can access your indexes
$list = $ticket['data']['list'];
$board = $ticket['data']['board'];
$card = $ticket['data']['card'];
}
If you don't like your $ticket['data'] as array, use as object instead $ticket['data']->list, $ticket['data']->board...
After json_decode you can this way retrieve 'list','board' and 'card' array data....May be help you..
$list=array();
$board=array();
$card=array();
foreach($json as $key => $value){
$list[]=$value[$key]['data']['list'];
$board[]=$value[$key]['data']['board'];
$card[]=$value[$key]['data']['card'];
}
echo "<pre>";
print_r($list);
print_r($board);
print_r($card);
You can access list array like below:
$list = $json['data']['list']
So access board array:
$board = $json['data']['board']
To access card array:
$card = $json['data']['card']
You get access for only 173 locaions array:
$list = $json[173]['data']['list'];
$board = $json[173]['data']['board'];
$card = $json[173]['data']['card'];
print_r($list);
print_r($board);
print_r($card);
you can get all of the array like
foreach ($json as $key => $value) {
$list[] = $value['data']['list'];
$board[] = $value['data']['board'];
$card[] = $value['data']['card'];
}
print_r($list);
print_r($board);
print_r($card);

Categories