I have a small PHP script that pulls in a CSV file and creates a JSON array from this.
However, I'd like to change the formatting of my outputted JSON array.
PHP:
<?php
$file = fopen('food.csv', 'r');
$allfile = [];
$idsColumnsWanted = array_flip([0, 1, 2]);
while (false !== $fields = fgetcsv($file)) {
$allfile[] = array_intersect_key($fields, $idsColumnsWanted);
}
fclose($file);
?>
Output:
var data = [["McDonalds","Fast Food","London"],["Marios","Italian","Manchester"]];
How do I transform my CSV into the following:
var data = [
{name:"McDonald's Fast Food",location:"London"},
{name:"Marios Italian",location:"Manchester"}
];
So it basically merges the first 2 items and adds name & location.
My food.csv file is:
McDonalds,Fast Food,London
Marios,Italian,Manchester
Next time please try something by yourself:
$data = [["McDonalds", "Fast Food", "London"], ["Marios", "Italian", "Manchester"]];
$newData = [];
foreach ($data as $info) {
$newData[] = [
'name' => $info[0] . " " . $info[1],
'location' => $info[2]
];
}
var_dump(json_encode($newData));
Output
string '[{"name":"McDonalds Fast Food","location":"London"},{"name":"Marios Italian","location":"Manchester"}]' (length=104)
You need to create a new array in the desired format, and simple json_encode it.
If you consider using jQuery - there it is
var data = [["McDonalds","Fast Food","London"],["Marios","Italian","Manchester"]];
var formated_data = {};
$.each(data, function(key, val) {
formated_data[key] = {name: val[0] + ' ' + val[1], location: val[2]}
});
console.log(formated_data);
Open CSV File then parse the CSV into an array.
Flow this Line,
<?php
$file="1_23.csv";
$csv= file_get_contents($file);
$array = array_map("str_getcsv", explode("\n", $csv));
$json = json_encode($array);
print_r($json);
?>
Related
The data returned by an API is in this format
[{"name":"Agnes ","amount":"40000"},{"name":"John","amount":"35000"},{"name":"Joyce","amount":"50000"},{"name":"Peter","value":"45000"}]
I want to re-format that output so that it looks like this:
Agnes-40000, John-35000, Joyce-50000, Peter-45000
So, I wrote something like this, letting $data represent the returned data above;
$new = json_decode($data);
foreach ($new as $key => $jsons) {
foreach($new as $key => $value) {
echo $value;
echo ",";
}
}
But the output I get is like: Agnes,40000, John,35000, Joyce,50000, Peter,45000
How do I write the javascript to display the data like
Agnes-40000, John-35000, Joyce-50000, Peter-45000
You have an array of objects. You need to concatenate the name and value properties.
$array = json_decode($data);
foreach ($array as $el) {
echo "{$el->name}-{$el->value},";
}
var jsonFromServer = '[{"name":"Agnes ","amount":"40000"},{"name":"John","amount":"35000"},{"name":"Joyce","amount":"50000"},{"name":"Peter","value":"45000"}]';
var json = JSON.parse(jsonFromServer);
var arrResult = []; // if array
//var textResult = ''; // if string
if(json && json.length){
for(var j = 0, jLen = json.length; j < jLen; j++){
var obIn = Object.values(json[j]);
var map = obIn.map(function(el){
return el.trim();
});
var res = map.join('-');
arrResult.push(res);
//textResult += res;
};
};
console.log(arrResult); // if array
//console.log(textResult); // if string
console result ["Agnes-40000", "John-35000", "Joyce-50000", "Peter-45000"]
Right now I have this PHP:
$columns = array(*/Data*/);
echo json_encode($columns);
And this is sent through an AJAX GET request with JQuery.
var columns = jQuery.parseJSON(response);
I would like to be able to send more than one array in the json_encode() is there any way to do this and how would you parse it with jQuery?
Sure, you could send an array of array. PHP associative array will become a javascript object.
In PHP:
$data = array();
$data['fruits'] = array('apple','banana','cherry');
$data['animals'] = array('dog', 'elephant');
echo json_encode($data);
and then on jQuery
var data = jQuery.parseJSON(response);
then you could then do something like this to access the values
console.log(data.fruits[0]); // apple
console.log(data.animals[1]); // elephant
The code should be like the following:
$columns = array(/*Data*/);
$columns1 = array(/*Data1*/);
echo json_encode(array($columns,$columns1));
in jQuery use
var columns_array=jQuery.parseJSON(response);
columns=columns_array[0];
columns1=columns_array[1];
$data1 = array();
$data2 = array();
$data1[] = array('apple','banana','cherry');
$data2[] = array('dog', 'elephant');
echo json_encode(array($data1,$data2));
in ajax,
console.log(response[0][0])//apple
console.log(response[1][0])//dog.....
After you have populated all the arrays namely $array1_json, $array2_json etc in my case,
$number_of_array1elements = count($array1_json);
$number_of_array2elements = count($array2_json);
$number_of_array3elements = count($array3_json);
array_unshift($array1_json , $number_of_array1elements);
// pushes element to the start of array1_json
array_unshift($array2_json , $number_of_array2elements);
array_unshift($array3_json , $number_of_array3elements);
and similarly for other arrays.
echo json_encode( array_merge($array1_json, $array2_json, $array3_json) );
In your .js file, use:
var val = xmlhttp.responseText;
var jsonData = JSON.parse(val);
var number_of_array1elements = jsonData[0];
for (var i = 1; i <= number_of_array1elements; i++ )
{
// use jsonData[i] to select the required element and do whatever is needed with it
}
var number_of_array2elements = jsonData[i];
for ( i = i+1; i <= number_of_array1elements+number_of_array2elements+1; i++ )
{
// use jsonData[i] to select the required element and do whatever is needed with it
}
I am trying to build common function for JSON to CSV Converter. currently for different json file i have to make some changes in existing function.
current code:
function JsonToCSV($jfilename, $cfilename) {
if (($json = file_get_contents($jfilename)) == false)
die('Error reading json file...');
$data = json_decode($json, true);
$fp = fopen($cfilename, 'w');
$header = false;
foreach ($data as $row) {
if (empty($header)) {
$header = array_keys($row);
fputcsv($fp, $header);
$header = array_flip($header);
}
fputcsv($fp, array_merge($header, $row));
}
fclose($fp);
return;
}
Above code is working for below json
[
{
"Id": "1",
"Name": "Juned Ansari",
"Position": "Full Stack Developer",
"Salary": "$99999"
},
{
"Id": "2",
"Name": "Mayur Marolia",
"Position": "Data Analyst",
"Salary": "$6789000"
},
{
"Id": "3",
"Name": "Mitesh Panchal",
"Position": "Team Leader",
"Salary": "$2324540"
}
]
but the problem is if my json structure changed then i have to rewrite above function like it is not working for below json
[
{
"BILLING_SOFTWARE_API_KEY": "ABCD1234",
"DISTRIBUTOR_API_KEY": "11380",
"SALESMANS": [
{
"sm_code": 1,
"sm_name": "DEEPAK MEHTA 7044524144"
},
{
"sm_code": 2,
"sm_name": "Juned Ansari"
}
]
}
]
The problem is that JSON is unstructured, while CSV is structured.
To clear this hurdle you must first of all gather all the JSON fields in all the structure, and since the header must be written first, you need to cycle through the JSON twice.
$columns = [ ];
// This could be a foreach
// foreach($data as $row) { $columns = array_merge($columns, array_keys($row)); }
array_map(function($row) use (&$columns) {
$columns = array_unique(array_merge($columns, array_keys($row)));
}, $data);
// Now columns contain all columns in all rows of the JSON.
$fp = fopen($cfilename, 'w');
fputcsv($fp, $columns);
// Set all empty fields to some default
$template = array_fill_keys($columns, '');
foreach ($data as $row) {
fputcsv($fp, array_values(array_merge($template, $row)));
}
fclose($fp);
The above will not function out of the box for complex data (if a column has sub-information, like in your example). There you need a more complex step:
foreach ($data as $row) {
$collapsed = array_map(function($value) {
if (is_array($value)) {
return implode(', ', $value);
}
return $value;
}, $row);
fputcsv($fp, array_merge($template, $collapsed));
}
Still more complex information in the JSON is a clear indication that you're doing this wrong. Your best bet is then to re-encode the complex value as JSON and store it as is in the CSV field (use json_encode() instead of implode, above).
The Great Column Name Massacre
For those cases where you need to throw bad money after worse, you can implement what I called the Great Column Name Massacre. In its easiest form, you code
{
"address": {
"street": "Piazza Vieusseux",
"number": 2,
"locality" : {
"type": "city",
"name": "Florence"
}
}
}
as
[
"address_street" => "Piazza Vieusseux",
"address_number" => 2,
"address_locality_type" => "city",
"address_locality_name" => "Florence"
]
I'm feeling of two minds about this. Please do not take this wrong, but I'm feeling sort of like you asked me why your Smith&Wesson battery-operated hair dryer is not working, even if you put all six batteries in the drum, pointed it to your head and pulled the trigger.
And I feel like I'm telling you "Oh, there's a safety switch on the side. You need to move it from SAFE to FIRE, or it will not work".
So bearing in mind that this looks like a very bad idea, the folding function I mentioned in the comments is this (you can adapt it to your needs, see later):
function fold($arry, $prefix = '') {
$retval = [ ];
foreach ($arry as $key => $value) {
$newkey = $prefix.$key;
if (is_array($value)) {
$folded = fold($value, $newkey . '_');
foreach ($folded as $subkey => $subval) {
$retval[$subkey] = $subval;
}
} else {
$retval[$newkey] = $value;
}
}
return $retval;
}
Once each element of the array has been folded, it can be analyzed to find out the column names (you can do this while folding) and then everything proceeds like above.
Testing
The folding function works properly with the provided JSON sample, and yields
Array
(
[BILLING_SOFTWARE_API_KEY] => ABCD1234
[DISTRIBUTOR_API_KEY] => 11380
[SALESMANS_0_sm_code] => 1
[SALESMANS_0_sm_name] => DEEPAK MEHTA 7044524144
[SALESMANS_1_sm_code] => 2
[SALESMANS_1_sm_name] => Juned Ansari
)
This of course immediately raises the first problem; "DISTRIBUTOR_API_KEY" is what we would expect from {"DISTRIBUTOR": {"API": {"KEY": 11380}}}. It works, but the decoding is ambiguous.
To overcome this limitation the quickest way is to change the delimiter from '_' to something else, or encode it differently in the keys.
Be warned: there will be no end of problems with this approach. If I had the time, I flatter myself fantasizing that I might end up with a post to rival the Famous Answer.
Having not the time, I hereby decline all responsibility for the frightful damage, loss of property, loss of productivity, loss of time, dereliction of duty, alienation of spouse and family ties and dire health consequences (included, but not limited to, a painful and prolonged death) that I believe are sure to follow.
I use simple client SIDE to convert JSON/HTML/XML to CSV,EXCEL...
because it is easy to download by attaching the file to download attribute of anchor tag...
here is an example you may like ...
The JS FIDDLE
$(document).ready(function(){
$('button').click(function(){
var data = $('#txt').val();
if(data == '')
return;
JSONToCSVConvertor(data, "Vehicle Report", true);
});
});
function JSONToCSVConvertor(JSONData, ReportTitle, ShowLabel) {
//If JSONData is not an object then JSON.parse will parse the JSON string in an Object
var arrData = typeof JSONData != 'object' ? JSON.parse(JSONData) : JSONData;
var CSV = '';
//Set Report title in first row or line
CSV += ReportTitle + '\r\n\n';
//This condition will generate the Label/Header
if (ShowLabel) {
var row = "";
//This loop will extract the label from 1st index of on array
for (var index in arrData[0]) {
//Now convert each value to string and comma-seprated
row += index + ',';
}
row = row.slice(0, -1);
//append Label row with line break
CSV += row + '\r\n';
}
//1st loop is to extract each row
for (var i = 0; i < arrData.length; i++) {
var row = "";
//2nd loop will extract each column and convert it in string comma-seprated
for (var index in arrData[i]) {
row += '"' + arrData[i][index] + '",';
}
row.slice(0, row.length - 1);
//add a line break after each row
CSV += row + '\r\n';
}
if (CSV == '') {
alert("Invalid data");
return;
}
//Generate a file name
var fileName = "MyReport_";
//this will remove the blank-spaces from the title and replace it with an underscore
fileName += ReportTitle.replace(/ /g,"_");
//Initialize file format you want csv or xls
var uri = 'data:text/csv;charset=utf-8,' + escape(CSV);
// Now the little tricky part.
// you can use either>> window.open(uri);
// but this will not work in some browsers
// or you will not get the correct file extension
//this trick will generate a temp <a /> tag
var link = document.createElement("a");
link.href = uri;
//set the visibility hidden so it will not effect on your web-layout
link.style = "visibility:hidden";
link.download = fileName + ".csv";
//this part will append the anchor tag and remove it after automatic click
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
I am trying to append content to json file using php script.
output of file1 is
[
{"id":"filters","name":"filter_supptype_cp_01"}
]
output of file2 is
[
{"id":"drives","name":"hddcntrlr"},
{"id":"drives","name":"diskdrivedes"}
]
after appending the output should come as :
[
{"id":"filters","name":"filter_supptype_cp_01"},
{"id":"drives","name":"hddcntrlr"},
{"id":"drives","name":"diskdrivedes"}
]
but output is coming as : -
[
{"id":"filters","name":"filter_supptype_cp_01"}]
[{"id":"drives","name":"hddcntrlr"},
{"id":"drives","name":"diskdrivedes"}
]
Code that I have tried is:
$file = file_get_contents('makejson.json');
$data = json_decode($file);
$info[] = array('id'=>$attribute1, 'name'=>$sub_attr_name);
$newb = array_values((array)$info);
file_put_contents('makejson.json',json_encode($newb),FILE_APPEND);
please help!!!!
Decode both files, append the array, encode again:
$existingData = json_decode(file_get_contents('file1.json'));
$newData = json_decode(file_get_contents('file2.json'));
$existingData = array_merge($existingData, $newData);
file_put_contents('file1.json', json_encode($existingData));
The array_push() function inserts one or more elements to the end of an array.
Your code :
$file = file_get_contents('makejson.json');
$tempArray = json_decode($file);
array_push($tempArray, $data); // $data is your new data
$jsonData = json_encode($tempArray);
file_put_contents('makejson.json', $jsonData);
i hope this code to help to yoo after 6 ear.
if (isset($_POST['data']) && $_POST['data']) {
$dbfile = file_get_contents('data.json');
$data = json_decode($dbfile);
unset($dbfile);
$yourdata = $_POST['data'];
$data[] = $yourdata;
file_put_contents('data.json', json_encode($data));
unset($data); }
You don't need to append array. You need to overwrite it.
Try like:
$file = file_get_contents('makejson.json');
$data = json_decode($file);
$data[] = array('id'=>$attribute1, 'name'=>$sub_attr_name);
file_put_contents('makejson.json',json_encode($data)); //Overwrite it
It will overwrite with new array.
This is kind of a strange one. I have a CSV that I'm uploading and passing to a PHP script that parses it into arrays, encodes it into a JSON string and sends it back to be further processed by my Javascript. However, I am having difficulty getting the response in a format that is easily parsed. Maybe it can be parsed, I'm just not sure how to access the data within.
PHP script for handling and parsing the CSV:
<?php
$file = $_FILES['file'];
$tmp = $file['tmp_name'];
$row = 1;
$json = array();
if(($handle = fopen($tmp, 'r')) !== false){
while(($data = fgetcsv($handle, 10000, '\n')) !== false){
$num = count($data);
$row++;
for($i = 0; $i < $num; $i++){
$values = split(',', $data[$i]);
$value = array(
sName => $values[0],
sNick => $values[1],
sEmail => $values[2],
sSSOID => $values[3],
sPwd => $values[4],
sConfPwd => $values[5],
sDescr => $values[6]
);
array_push($json, $value);
}
print_r(json_encode($json));
}
fclose($handle);
}
?>
The output ends up being an iterative response where the first array contains the first row of the CSV and the second array contains the first and second rows (the third array contains the first, second, and third, etc. etc.). The very last array is the response that I want. It is a well-formed JSON string; I am just unsure of how to get only that response.
Sample response:
[{"sName":"John Doe","sNick":"John","sEmail":"jdoe#email.com","sSSOID":"jdoe","sPwd":"Admin1234","sConfPwd":"Admin1234","sDescr":"Likes cats"}][{"sName":"John Doe","sNick":"John","sEmail":"jdoe#email.com","sSSOID":"jdoe","sPwd":"Admin1234","sConfPwd":"Admin1234","sDescr":"Likes cats"},{"sName":"Bill Frank","sNick":"Bill","sEmail":"bfrank#email.com","sSSOID":"bfrank","sPwd":"Admin1234","sConfPwd":"Admin1234","sDescr":"Likes dogs"}][{"sName":"John Doe","sNick":"John","sEmail":"jdoe#email.com","sSSOID":"jdoe","sPwd":"Admin1234","sConfPwd":"Admin1234","sDescr":"Likes cats"},{"sName":"Bill Frank","sNick":"Bill","sEmail":"bfrank#gmail.com","sSSOID":"bfrank","sPwd":"Admin1234","sConfPwd":"Admin1234","sDescr":"Likes dogs"},{"sName":"Sam Smith","sNick":"Sam","sEmail":"ssmith#email.com","sSSOID":"ssmith","sPwd":"Admin1234","sConfPwd":"Admin1234","sDescr":"Likes music"}]
The only response I need is the final array:
[{"sName":"John Doe","sNick":"John","sEmail":"jdoe#email.com","sSSOID":"jdoe","sPwd":"Admin1234","sConfPwd":"Admin1234","sDescr":"Likes cats"},{"sName":"Bill Frank","sNick":"Bill","sEmail":"bfrank#email.com","sSSOID":"bfrank","sPwd":"Admin1234","sConfPwd":"Admin1234","sDescr":"Likes dogs"},{"sName":"Sam Smith","sNick":"Sam","sEmail":"ssmith#email.com","sSSOID":"ssmith","sPwd":"Admin1234","sConfPwd":"Admin1234","sDescr":"Likes music"}]
You might want to use
$json[] = $value;
instead of array_push and
echo json_encode($json);
instead of print_r. Also, move the print_r/echo call out of the while loop.
Move this line to after the fclose:
print_r(json_encode($json));
Try this:
$index = count($json) - 1;
echo json_encode($json[$index]);
Decode the JSON in your Javascript app, which will produce an array, then use .pop() to get the last value:
var json = json_decode('[{"sName" ......... ');
var lastelement = json.pop();