Array to nested Json - php

I try to convert some data into a json. The data looks like this:
$one = ["ID","Name","Address1","Address2"];
$two = ["KJS0001","Mike","Cairo","Egypt"];
$three = ["KHO0001","Jhon","Paris","France"];
The Output I want to get is:
{
"KJS0001":{
"Name":"Mike",
"Address":["Cairo","Egypt"]
},
"KHO0001":{
"Name":"Jhon",
"Address":["Paris","France"]
}
}
Since the amount of nested attributes varies and its indexed with id also how to make Address (contain data from address1 and address2 array). Can anyone help me?

This is one possible solution, By creating new array and use json_encode
<?php
$data = array();
//$columns = ["ID","Name","Address1","Address2"];
$data[] = ["KJS0001","Mike","Cairo","Egypt"];
$data[] = ["KHO0001","Jhon","Paris","France"];
$result = array();
foreach($data as $value){
$result[] = [$value[0] => ["Name"=>$value[1],"Address"=>[$value[2],$value[3]] ] ];
}
echo json_encode($result);
?>
Column name, you mentioned in $one is not needed if columns are fixed.
Live demo : https://eval.in/621908
Output is :
[
{"KJS0001":{"Name":"Mike","Address":["Cairo","Egypt"]}},
{"KHO0001":{"Name":"Jhon","Address":["Paris","France"]}}
]

Related

php filtering json file and returning an attribute value

I have a json file which I read in. I want to first filter the json data to return the object defined by the datasetID, then get out the datasetName. I have filtered in javascript, but would prefer to stay in php but I can't figure it out, any ideas?
note: foreach is not required as only a single record is returned when filtered using the datasetID. So rather than using a foreach method how would you swelect a single record, first for instance?
$datasetID = '5fd4058e5c8d2'; // unique 13 character string
$data = json_decode(file_get_contents(path/to/file), True);
So I need to first filter for the unique object with $datasetID = '5fd4058e5c8d2';
$filtered_data =
Then I need to return the attribute datasetName from that object
$datasetName =
pointers to the best ways to do this is welcomed.
Sample json data:
[
[
{
"datasetID":"5fd4124900827",
"institutionCode":"None",
"collectionCode":"None",
"datasetName":"None"
}
],
[
{
"datasetID":"5fd4058e5c8d2",
"institutionCode":"None",
"collectionCode":"None",
"datasetName":"None",
}
]
]
I don't know how you got that JSON but it is nested deeper than needed. You can merge the top level arrays to flatten it, then index on datasetID:
$data = array_merge(...$data);
$filtered_data = array_column($data, null, 'datasetID')[$datasetID];
$datasetName = $filtered_data['datasetName'];
Shorter:
$filtered_data = array_column(array_merge(...$data), null, 'datasetID')[$datasetID];
$datasetName = $filtered_data['datasetName'];
Or to keep them all to use:
$data = array_column(array_merge(...$data), null, 'datasetID');
$datasetName = $data[$datasetID]['datasetName'];
I tried with your sample JSON.
First, json_decode will return a PHP array to use foreach on it. I wrote a simple foreach and checked your searching ID is equal to element's datasetID. If it is equal this is the datasetName you are searching for.
<?php
$json = '[[{"datasetID":"5fd4124900827","institutionCode":"None","collectionCode":"None","datasetName":"None"}],[{"datasetID":"5fd4058e5c8d2","institutionCode":"None","collectionCode":"None","datasetName":"None"}]]';
$elements = json_decode($json,TRUE);
$searchingID = "5fd4058e5c8d2";
foreach ($elements as $element) {
if(isset($element[0]['datasetID']) && $element[0]['datasetID'] == $searchingID){
$filtered_data = $element[0];
break;
}
}
echo $filtered_data['datasetName']; // or return $filtered_data['datasetName'];
?>

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 insert item at the beginning of a associative array in php

I am currently trying to group my data based on date and some name. Here is my code
$data = [];
foreach($allmatches as $d){
$name = $d['div']['divisionName'];
$data[$d['playingDate']][$name][]=$d;
$data[$d['playingDate']]['day']=$d['day'];
$data[$d['playingDate']]['month']=$d['month'];
$data[$d['playingDate']]['isToday']=$d['isToday'];
}
return $data;
OUTPUT
======
2018-09-18: {
Elitserien: [+],
day: "18",
month: "Sep",
isToday: true,
Division 2: [+],
Division 5: [+]
},
Current out put starts with Elitserien but I want to achieve Division 5 at the beginning..
To help further, here is a picture of the current data
I want to insert the new element always at the beginning of the array. How can I do it? Thank you so much.
Because you are using an associative array, you need to use array_merge to prepend the series data (i.e. data indexed by $name to the beginning of the $data[$d['playingDate']] array. This code will do what you want. Note that I've put the series code at the end to avoid having to check for $data[$d['playingDate']] being set as well as $data[$d['playingDate']][$name].
$data = [];
foreach($allmatches as $d){
$name = $d['div']['divisionName'];
$data[$d['playingDate']]['day']=$d['day'];
$data[$d['playingDate']]['month']=$d['month'];
$data[$d['playingDate']]['isToday']=$d['isToday'];
if (!isset($data[$d['playingDate']][$name])) $data[$d['playingDate']] = array_merge(array($name => array()), $data[$d['playingDate']]);
$data[$d['playingDate']][$name][]=$d;
}
I've created a small demo on 3v4l.org
You can simply use + operator:
$data = [];
foreach($allmatches as $d){
$name = $d['div']['divisionName'];
// Prepare a temp array
$temp = array();
$temp[$name][] = $d;
$temp['day'] = $d['day'];
$temp['month'] = $d['month'];
$temp['isToday'] = $d['isToday'];
// Add to the beginning of $data array (first-level)
$data = array($d['playingDate'] => $temp) + $data;
}
return $data;
array_unshift() function will fix your problem.

PHP/MYSQL: Access data in Array of Dictionaries

I receive a JSON stream from an iphone that contains some simple strings and numbers as well as an array of dictionaries. I would like to work with these dictionaries, in essence, storing the data in each of them in a separate MYSQL record.
To get access to the strings as well as the array from the JSON stream, I am using the following:
$jsonString = file_get_contents('php://input');
$jsonArray = json_decode($jsonString, true);
$authString = jsonArray['authstring'];
$itemsArray = $jsonArray['itemsArray'];
This is what itemsArray looks like before being sent to the server:
itemsArray = (
{
lasttouchedstr = "2018-07-09 17:24:56";
localiid = 6;
iid = 0;
title = "test";
complete = 1;
userid = 99;
whenaddedstr = "2018-06-21 14:10:23";
},
{
lasttouchedstr = "2018-07-09 17:24:56";
localiid = 37;
iid = 0;
title = "how about this";
userid = 88;
whenaddedstr = "2018-07-07 16:58:31";
},
{
lasttouchedstr = "2018-07-09 17:24:56";
localiid = 38;
iid = 0;
title = reggiano;
userid = 1;
whenaddedstr = "2018-07-07 17:28:55";
}
etc.
I guess I should probably put these dictionaries into an Associative Array in order to save them.
I am struggling, however, with how to reference and get the objects. From what I can tell the following code is returning empty values in so far as $message comes back as empty.
$anitem = $jsonArray['itemsArray'][0];
$message=$anitem;
$title = $jsonArray['itemsArray'][0].[item];
$message.=$title;
Can anyone suggest proper syntax to grab these items and their properties?
Thanks in advance for any suggestions.
I find it strange that people associate things with a dictionary, while it is nothing more then a multidimensional array.
If you can read JSON, you see that the variable will have an index containing each entry.
For PHP:
foreach($jsonArray as $array){
// note that $array is still an array:
foreach($array as $v){
echo "Hurray!: '$v'";
}
}
If it really was an object (or cast to an object), the only thing you need to change is how you access the variable (as in any other language). In PHP it would be:
echo $jsonArray[0]->lasttouchedstr;
Or of it was the same loop:
foreach($jsonArray as $v){
echo $v->lasttouchedstr;
}
Multidimensional?
echo $jsonArray['itemsArray'][0][item]; // array
echo $jsonArray->itemsArray[0][item]; // if items array is an actual array and jsonArray an object.
Most languages associate things written as a . that the left side is an object. In PHP it's written as ->.

Need to create Json object in php

I want to create a json object using php like below as I need to create a stacked bar chart using d3.js, hence I am using data from oracle table and need the json data as above image.
My table has these 3 columns. (ID, NAME, Layers) like:-
ID, NAME, Layers
1 ABC a:8,b:10
2 WWW c:8,d:7
When I am fetching data from oracle, my php code is:-
while (($row = oci_fetch_array($stid, OCI_ASSOC))) {
$streamArr[] = $row;
}
header("Access-Control-Allow-Origin: *");
echo json_encode($streamArr);
I am getting this error:-
Warning: [json] (php_json_encode) type is unsupported, encoded as null in line 48
json output as:-
[["1","ABC",{"descriptor":null}],["2","WWW",{"descriptor":null}]]
can you please help me in rectifying with this issue?
The error message refers to a field you didn't mention in the example. Maybe just don't select unneeded fields?
If you fix that, you still won't get the desired JSON structure. To get layers as an object in every element of data in the resulting JSON, you need to convert the string values stored in the database to PHP arrays before encoding.
You could do that with similar code:
while (($row = oci_fetch_array($stid, OCI_ASSOC)))
{
$row['layers'] = array_map(function($el) {
return explode(':', $el);
}, explode(',', $row['layers']));
$streamArr[] = $row;
}
#marekful answer is really nice, not easiest to understand but efficient and short!
Here you have a longer and not so efficient, but maybe easier to get.
$streamArr = array();
while (($row = oci_fetch_array($stid, OCI_ASSOC)))
{
// Get ID and NAME
$data = array(
'id' => $row['ID'],
'name' => $row['NAME'],
'layers' => array()
);
// Get Layers by split by comma
$layers = explode(',', $row['layers']);
foreach ($layers as $layer) {
// Get layer parts by slit with double-point
$layersPart = explode(':', $layer);
foreach ($layersPart as $key => $value) {
$data['layers'][$key] = $value;
}
}
// Add to global array
$streamArr[] = $data;
}
echo json_encode($streamArr);

Categories