I was given a task to sort out data from a text file into JSON using PHP and object oriented principal.
The text file has information and is displayed as follows (ignore #):
#product_num:name:cost
5:tv:59.99
7:radio:10.99
I created a class and in this class I have one function that ignores any # or blank spaces from the data and puts the data in an array and json_encode it. When I echo this data it looks like this:
[{"1":"5:tv:59.99","2":"7:radio:10.99"}]
Is it possible to write other functions to separate the data further, for example so it looks more like:
[{"product_number":"5","name":"tv","cost":"59.99"},{"product_number":"7","name":"radio","cost":"10.99"}]
If so can anyone give me any pointers and tips because I have no idea where or how to begin even after numerous google searches.
There is a function inside PHP for reading value separated lines, like CSV; it's called fgetcsv which can also be used in object oriented PHP through SplFileObject::fgetcsv.
You will need to read each line, add the variable labels then append that to an array.
Depending on the size of the file you may need to optimize for memory usage as your array grows by saving as you proceed through the file.
<?php
$file = new SplFileObject('test.txt', 'r'); //Load the file
$file->current(); //Skip the first line (Side note: seek(1) did not appear to work while testing)
$result = [];
do { //While there are lines in the file
list($product_num, $name, $cost) = $file->fgetcsv(':'); //Break the line on the : delimiter into an array and populate the array into the three named values
$result[] = [ //Build the new json representation and add to result array
'product_num' => $product_num,
'name' => $name,
'cost' => $cost,
];
} while (!$file->eof());
file_put_contents('output.json', json_encode($result)); //Save the result
Your file format is basically a csv file and PHP has a CSV import function.
http://php.net/manual/en/function.fgetcsv.php
If you scroll down and check the CsvImporter example, you can copy/paste that and add a json_encode:
$importer = new CsvImporter("small.txt",true,":");
$data = $importer->get();
echo json_encode($data);
[{
"\ufeff#product_num": "5",
"name": "tv",
"cost": "59.99"
},
{
"\ufeff#product_num": "7",
"name": "radio",
"cost": "10.99"
}]
Related
I must convert a php associative array to CSV like:
[
["a"=>1, "b"=>2, "c"=>3],
["a"=>5, "b"=>6, "c"=>6],
["a"=>7, "b"=>8, "c"=>9, "d"=>10]
]
must output a string like
a;b;c;d
1;2;3;
4;5;6;
7;8;9;10
I already implement this logic using only foreach and implodes. However CSV has some features like knowing when scape chars and when to quote cells.
I've been used https://www.papaparse.com/ (javascript) a lot for the front-end side.
Is there a Composer package which can do the job?
PS. I need the CVS as string not to save to a file.
You can use fputcsv to get properly formatted CSV, saving to memory and then save it to a variable:
$fh = fopen('php://memory', 'r+');
foreach($array as $row) {
fputcsv($fh, $row); // add other args as needed
}
$csv = stream_get_contents($fh, -1, 0);
//or
rewind($fh);
$csv = stream_get_contents($fh);
You can also use php://temp which will use memory up to a limit and then write to a temporary file or you can generate your own temporary file with tmpfile.
I'm making an API where the user sends an CSV to my page in binary code.
I need to read that CSV and read all rows in that CSV.
Inside that loop I'm adding each row to the DB.
I don't know how to do that.
Currently I'm using fgetcsv but that function can't be used to read binary files.
Thats only used for Posting CSV files in a POST.
I'm sending a CSV file through a HTTP request.
My result looks like this:
"person 1", "street 4", "test#gmail.com",,, "florida", "person 2", "street 5", "test2#gmail.com",,, "florida"
To iterate over each line and data in there you can use this format:
$lines = explode("\r\n", $data); // split the string by new lines
foreach($lines as $line){ // Loop over each line
$column = explode(",", $line); // split the line in 'columns'
$name = $column[0];
$street = $column[1];
}
I need to generate 2 JSON files with PHP from 2 TCP commands in order to build a Highchart graph.
The first JSON file will contain the graph informations :
Graph Title, Graph Subtitle, Y axis title and a number related to the type of graph to be displayed.
The TCP string (from an IoT distant board) sends to the server the following arguments :
Name of JSON info file to built
Graph Title
Graph Subtitle
Graph Y axis title
Type of graph to be displayed
http:myserver/graphs/make-json_info.php?jsonfilename=S_007_nfo.json&graphtitle=S_007_Sensor&graphsubtitle=Office-Temp&Yaxistitle=Temp-Sensor&GraphType=3
How could i make a JSON file with a PHP file named 'make-json_info.php' from this TCP string ?
JSON file should look like this :
{
chart: {
type: '/*...*/'
},
xAxis: {/*...*/},
yAxis: {/*...*/},
plotOptions: {/*...*/}
/*...etc...*/
}
Regarding the 2sd JSON file needed to generate the graph, the IoT board sends every minutes another TCP string that contains :
Name of JSON data file to fill-in
Datetime stamp
Sensor value
http:myserver/graphs/make-json_data.php?S_007_data.json&datatime=1488271800000&value=22.5
Expected JSON file should be like this :
http://s529471052.onlinehome.fr/graphs/S_007_data.json
Can you show me how to write my two PHP files, these should generate 2 JSON files in order to built the expected Highcharts Graph afterwards ?
So far, i tried to extract informations from the JSON data file and JSON info file fro graph information is missing.
see jsfiddle below
http://jsfiddle.net/fbmohjgy/
I'm uncertain about many things in you question, but I will try my best.
The JSON file that contain the graph information... Does it only contain meta infromation about the graph (title, type, etc), or does the file also contains xAxis Data and yAxis Data...
From these two lines in your question, it seems like it may also contains the actual data:
xAxis: {/*...*/},
yAxis: {/*...*/},
Apologies if I got it all wrong, but this is what I came up with.
It is not tested, but should give you an idea of what to do:
Let's start with the second file/script first.
<?php
$file_name = $_GET['jsonfilename'];
$datatime = $_GET['datatime'];
$value = $_GET['value'];
$file_content = file_get_contents($file_name); //read data from json file
$temp_file_data = json_decode($file_content, true); //convert json string into php array
$temp_file_data['date'][] = [$datatime, $value]; //add your new values to the array
$new_file_content = json_encode($temp_file_data); //encode your new array as a json string
file_put_contents($file_name, $new_file_content); //save the new json string back to the file
?>
Now for the first PHP script. This script will use the json file from the above code to create the complete json file that the graph will use:
<?php
$file_name = $_GET['jsonfilename'];
$graphtitle = $_GET['graphtitle'];
$graphsubtitle= $_GET['graphsubtitle'];
$Yaxistitle= $_GET['Yaxistitle'];
$GraphType = $_GET['GraphType'];
$data_json = file_get_contents($file_name); //read data from json file
$data_array = json_decode($file_content, true); //convert json string into php array
$xAxis = []; //create array that will contain all xAxis values
$yAxis = []; //create array that will contain all yAxis values
for($i = 0; $i < sizeof($data_array['data']); $i++)
{
$xAxis[] = $data_array['data'][$i][0]; //add xAxis data from first json file to the xAxis array
$yAxis[] = $data_array['data'][$i][1]; //add yAxis data from first json file to the yAxis array
}
$json_array = []; //declare the array that will be converted to the final JSON string that the graph will use
$json_array['chart'] = ['type' => $GraphType];
$json_array['xAxis'] = $xAxis;
$json_array['yAxis'] = $yAxis;
$json_array['plotOptions'] = ['graphtitle' => $graphtitle,
'graphsubtitle' => $graphsubtitle,
'Yaxistitle' => $Yaxistitle];
?>
How do I add to a .json file with PHP? Currently, I'm appending a .json file with PHP, but it won't add the data to an existing JSON object. It makes a new object. I need the data all stored in one object, in an external JSON file. Basically, I have a JSON object and want to add more values to it.
$jsonFile = "test.json";
$fh = fopen($jsonFile, 'w');
$json = json_encode(array("message" => $name, "latitude" => $lat, "longitude" => $lon, "it" => $it));
fwrite($fh, $json);
You can decode the json file to a php array, then insert new data and save it again.
<?php
$file = file_get_contents('data.json');
$data = json_decode($file);
unset($file);//prevent memory leaks for large json.
//insert data here
$data[] = array('data'=>'some data');
//save the file
file_put_contents('data.json',json_encode($data));
unset($data);//release memory
what's suggested above is the hard way. i am considering there should be an easier way, to literally append an array into the json file.
here is the algo:
$handle=fopen($jsonFile);
fseek($handle,-1,SEEK_END);
fwrite($handle,$arrayToAdd);
fclose($handle);
but i am not sure it's more cpu/memory efficient to do so than reading the whole json file into memory, adding the array and then getting it stored.
Is it possible to write at a particular location in a CSV file using PHP?
I don't want to append data at the end of the CSV file. But I want to add data at the end of a row already having values in the CSV.
thanks in advance
No, it s not possible to insert new data in the middle of a file, due to filesystem nature.
Only append at the end is possible.
So, the only solution is to make another file, write a beginning part of source, append a new value, and then append the rest of the source file. And finally rename a resulting file to original name.
There you go. Complete working code:
<?php
//A helping function to insert data at any position in array.
function array_insert($array, $pos, $val)
{
$array2 = array_splice($array, $pos);
$array[] = $val;
$array = array_merge($array, $array2);
return $array;
}
//What and where you want to insert
$DataToInsert = '11,Shamit,Male';
$PositionToInsert = 3;
//Full path & Name of the CSV File
$FileName = 'data.csv';
//Read the file and get is as a array of lines.
$arrLines = file($FileName);
//Insert data into this array.
$Result = array_insert($arrLines, $PositionToInsert, $DataToInsert);
//Convert result array to string.
$ResultStr = implode("\n", $Result);
//Write to the file.
file_put_contents($FileName, $ResultStr);
?>
Technically Col. Shrapnel's answer is absolutely right.
Your problem is that you don't want to deal with all these file operations just to change some data. I agree with you. But you're looking for the solution in a wrong level. Put this problem in a higher level. Create a model that represents an entity in your CSV database. Modify the model's state and call its save() method. The method should be responsible to write your model's state in CSV format.
Still, you can use a CSV library that abstracts low level operations for you. For instance, parsecsv-for-php allows you to target a specific cell:
$csv = new parseCSV();
$csv->sort_by = 'id';
$csv->parse('data.csv');
# "4" is the value of the "id" column of the CSV row
$csv->data[4]['firstname'] = 'John';
$csv->save();