I have a CSV file (my_data.csv) that I want to convert to JSON object.
With column ";" it gives me wrong result, with comma "," it works fine.
But I don't want edit the csv file. And I don't want use str_replace because the csv file is huge and it will take longer.
How can I change my conversion function to generate the correct JSON format ?
Here is my CSV file:
"Timestamp";"Longitude";"Latitude";"Client";"Price"
"2015-08-01 05:10:13";10.714069;48.031952;"test1";17.2
"2015-08-01 05:10:13";10.714069;48.031952;"test2";17.2
"2015-08-01 05:10:13";10.714069;48.031952;"test3";17.2
"2015-08-01 05:10:13";10.714069;48.031952;"test4";17.2
This is my PHP code
$file="data/my_file.csv";
$csv= file_get_contents($file);
$rows = explode("\n", trim($csv));
$data = array_slice($rows, 1);
$keys = array_fill(0, count($data),$rows[0] );
$json = array_map(function ($row, $key) {
return array_combine(str_getcsv($key), str_getcsv($row));
}, $data, $keys);
$data=json_encode($json);
echo $data;
I get this :
[{"Timestamp;\"Longitude\";\"Latitude\";\"Client\";\"Price\"":"2015-08-01 05:10:13;10.714069;48.031952;\"test1\";17.2"},
{"Timestamp;\"Longitude\";\"Latitude\";\"Client\";\"Price\"":"2015-08-01 05:10:13;10.714069;48.031952;\"test2\";17.2"},
{"Timestamp;\"Longitude\";\"Latitude\";\"Client\";\"Price\"":"2015-08-01 05:10:13;10.714069;48.031952;\"test3\";17.2"},
{"Timestamp;\"Longitude\";\"Latitude\";\"Client\";\"Price\"":"2015-08-01 05:10:13;10.714069;48.031952;\"test4\";17.2"}]
It should be this :
[{"Timestamp":"2015-08-01 05:10:13","Longitude":"10.714069","Latitude":"48.031952","Client":"test1","Price":"17.2"},
{"Timestamp":"2015-08-01 05:10:13","Longitude":"10.714069","Latitude":"48.031952","Client":"test2","Price":"17.2"},
{"Timestamp":"2015-08-01 05:10:13","Longitude":"10.714069","Latitude":"48.031952","Client":"test3","Price":"17.2"},
{"Timestamp":"2015-08-01 05:10:13","Longitude":"10.714069","Latitude":"48.031952","Client":"test4","Price":"17.2"}]
You have to change
return array_combine(str_getcsv($key), str_getcsv($row));
to
return array_combine(str_getcsv($key, ';'), str_getcsv($row, ';'));
Because the default value of parameter $delimiter is ',':
array str_getcsv ( string $input [, string $delimiter = "," [, string
$enclosure = '"' [, string $escape = "\" ]]] )
Alternative solution:
<?php
$csvString = file_get_contents('/path/to/data.csv');
$csvRows = str_getcsv($csvString, "\n"); // split new lines, gives you rows
$rows = array();
foreach($csvRows as $row) {
$rows[] = str_getcsv($row, ";"); // parse the rows
}
// remove the first row. its the CSV column heading line. keep keys for reuse.
$itemKeys = array_shift($rows);
// run over all rows and combine keys with values, to get a named array
foreach($rows as $rowKeys => $rowValues) {
$array[] = array_combine($itemKeys, $rowValues);
}
echo json_encode($array);
Result:
[{"Timestamp":"2015-08-01 05:10:13","Longitude":"10.714069","Latitude":"48.031952","Client":"test1","Price":"17.2"},
{"Timestamp":"2015-08-01 05:10:13","Longitude":"10.714069","Latitude":"48.031952","Client":"test2","Price":"17.2"},
{"Timestamp":"2015-08-01 05:10:13","Longitude":"10.714069","Latitude":"48.031952","Client":"test3","Price":"17.2"},
{"Timestamp":"2015-08-01 05:10:13","Longitude":"10.714069","Latitude":"48.031952","Client":"test4","Price":"17.2"}]
Related
I am using PHP and converting the JSON data into the CSV format and later on read the same CSV file for further processing.
Below is my code that converts the JSON data in to the CSV format.
function LoadDataFromFile($file)
{
$json = file_get_contents($file);
$array = json_decode($json, true);
$f = fopen('out.csv', 'w');
$firstLineKeys = false;
$keys = array();
//first collect keys
foreach($array as $line){
foreach($line as $key => $value){
if(!in_array($key, $keys))
$keys[] = $key;
}
}
$keyString = implode(",", $keys);
fwrite($f, "$keyString\n");
foreach ($array as $line)
{
$outputArray = array();
foreach($keys as $key){
if(array_key_exists($key, $line)){
$outputArray[] = str_replace(',', '', $line[$key]);;
} else {
$outputArray[] = "";
}
}
$outputString = implode(",", $outputArray);
fwrite($f, "$outputString\n");
}
fclose($f);
}
As we can see that, i am writing data into the "out.csv" file, and later on i am reading same CSV file and assign the value/ full contents of the same file line by line to $array variable, as shown below.
$array = explode("\n", file_get_contents('out.csv'));
Now, I want to directly assign the value of csv contents into the $array variable with out using the intermediate "out.csv" file.
Wondering what data structure should i use while converting JSON data to CSV format, and possible code changes required for "LoadDataFromFile" method?
If you can already convert the json into csv, then just append the output strings together assigned to a string variable instead of writing it to a file. Or am I misunderstanding what you want?
Instead of:
fwrite($f, "$outputString\n");
you can put:
$csv .= $outputString;
And finish it with:
$array = explode("\n", $csv);
I am trying to update last line of a csv file, I get the last line with using this code:
$f = public_path('MYCSV.csv');
$rows = file($f);
$last_row = array_pop($rows);
$data = str_getcsv($last_row);
I searched a lot but did not find any way to replace or at least to remove the last line of csv file, it will be great if do not use foreach loop as the file size is big...
Code: (I don't have Laravel to test on, but I tested with raw php)
$f = public_path('MYCSV.csv');
$rows = file($f);
array_pop($rows); // remove final element/row from $array
file_put_contents($f, implode($rows)); // convert back to string and overwrite file
Now if you want to add a new row to the end of your file, you will just need to push the new data as a comma-separated string (with a trailing newline character) into the $rows array.
If you have a .csv file with this content:
Sally Whittaker,2018,McCarren House,312,3.75
Belinda Jameson,2017,Cushing House,148,3.52
Jeff Smith,2018,Prescott House,17-D,3.20
Sandy Allen,2019,Oliver House,108,3.48
Then $rows array, after the array_pop() call, will be:
array (
0 => 'Sally Whittaker,2018,McCarren House,312,3.75
',
1 => 'Belinda Jameson,2017,Cushing House,148,3.52
',
2 => 'Jeff Smith,2018,Prescott House,17-D,3.20
')
*Notice that the newline characters are not lost when file() is used -- so no "glue" is necessary with implode().
After file_put_contents() is called, the file will be overwritten with:
Sally Whittaker,2018,McCarren House,312,3.75
Belinda Jameson,2017,Cushing House,148,3.52
Jeff Smith,2018,Prescott House,17-D,3.20
<?php try {
$csv_path = 'MYCSV.csv';
$fp = fopen($csv_path, 'r+');
if ($fp) {
$data = array();
while ($row = fgetcsv($fp)) {
$data[] = $row;
}
fclose($fp);
array_pop($data);
$fp = fopen($csv_path, 'w+');
foreach($data as $key => $value) {
fputcsv($fp, $value);
}
} else {
throw new Exception("Failed to open file");
}
} catch (Exception $e) {
echo $e -> getMessage();
}?>
I have a file with many rows,each row have the following format:
1519382994.85#MSG#Something went wrong
So, for each row i have three field divided by #. A number, a message type and a string.
Now i want to read the file and split the contents.
I made it in this way:
//Opening the logger file
$myfile = file_get_contents("operations.txt", "r") or die("Unable to open file!");
$rows = explode("\n", $myfile);
$num_rows = count($rows);
$fieldList = array();
//Parsing rows using '#'
foreach ($rows as $row => $data) {
$row_data = explode('#', $data);
array_push($fieldList, (string)$row_data[0]);
array_push($fieldList, (string)$row_data[1]);
array_push($fieldList, (string)$row_data[2]);
}
The code is working well but i'd like to have an array of array and this kind of data:
0: Array [ "112323.76", "MSG", "Hello"]
1: Array [ "453435.78", "MSG", "Bye"] etc..
I tryed with this code but i'm doing something wrong.
$last=0;
$result = array();
for ($i = 0; $i < $num_rows; $i++) {
array_push($result, (string) $fieldList[$last], (string) $fieldList[$last+1],(string) $fieldList[$last+2]);
//echo $fieldList[$last].'<br>';
//echo $fieldList[$last+1].'<br>';
//echo $fieldList[$last+2].'<br>';
$last=$last+3;
}
I'm a newbie in PHP someone can help me please and tell me what i'm doing wrong? Tanx a Lot for your time
You could probably make use of the built-in fgetcsv:
array fgetcsv ( resource $handle [, int $length = 0 [, string $delimiter = "," [, string $enclosure = '"' [, string $escape = "\\" ]]]] )
This could look like:
$rows = [];
if (false !== ($handle = fopen("path/to/file", "r")))
{
while (false !== ($row = fgetcsv($handle, 1000, ",")))
{
array_push($rows, $row);
}
fclose($handle);
}
Don't know if it would be a lot faster, but looks a lot easier to me. The main benefits of this over file() and explode() are:
There is no need to have the entire file in RAM at once, processing could be done one row at a time.
it is easy to support other "Character Seperated Values" type files where fields may be quoted ($enclosure)
Just needed some modifications in your code. Added comments to modified lines-
$myfile = file_get_contents("operations.txt", "r") or die("Unable to open file!");
$rows = explode("\n", $myfile);
$num_rows = count($rows);
$finalFieldList = array(); // new array
//Parsing rows using '#'
foreach ($rows as $row => $data) {
$fieldList = array(); // temporary array
$row_data = explode('#', $data);
array_push($fieldList, (string)$row_data[0]);
array_push($fieldList, (string)$row_data[1]);
array_push($fieldList, (string)$row_data[2]);
array_push($finalFieldList, $fieldList); // it will push to final array containing all 3 values
}
I have a text file like this:
filter 'no'
interval '15'
phonenumbers ''
color 'purple'
version '24/10/2016'
And I want to turn in into an array so when I do $array['filter'] the output should be no and when I do $array['color'] the output should be purple here's what I've tried so far:
<?php
$txt_file = file_get_contents('/home/ab/mytext.txt');
$rows = explode("'", $txt_file);
var_dump($rows);
?>
But it doesn't work, how can I do this ?
You should just put it into CSV format, and make the first token the key and the second token the value.
filter, no
interval, 15
Then just explode by new line and parse
$file = file_get_contents(...);
$lines = explode($file, "\n");
foreach($lines as $line) {
$l = str_getcsv($line);
// assign stuff to array
}
Try this:
$txt_file = file_get_contents('/home/ab/mytext.txt');
// explode to lines
$rows = explode( PHP_EOL, $txt_file);
$result = array();
foreach( $rows as $row ){
// explode each line by space
$parts = explode( ' ', $row );
// set values of arrray
$result[ $parts[0] ] = trim( $parts[1], '\'' );
}
echo $result['color'];
PHP's built-in file function can get file contents into array. Each value in the array is the corresponding line in the file. Explode each line into an array based on the space delimiter. This is the code you might be looking for:
<?php
$txt_file = file('/home/ab/mytext.txt', FILE_IGNORE_NEW_LINES);
foreach($txt_file as $value) {
$value_exploded = explode(' ', $value);
$arr[$value_exploded[0]] = $value_exploded[1];
}
var_dump($arr);
echo $arr['filter'];
?>
Hope it helps!
if i use the following code i got data in text file
{"title":"sankas","description":"sakars","code":"sanrs"}
{"title":"test","description":"test","code":"test"}
but my code is working on
{"title":"sankas","description":"sakars","code":"sanrs"}
so i could not add more rows.where i want to change to get correct results.
$info = array();
$folder_name = $this->input->post('folder_name');
$info['title'] = $this->input->post('title');
$info['description'] = $this->input->post('description');
$info['code'] = $this->input->post('code');
$json = json_encode($info);
$file = "./videos/overlay.txt";
$fd = fopen($file, "a"); // a for append, append text to file
fwrite($fd, $json);
fclose($fd);
use php's file_put_content() more information here http://php.net/manual/en/function.file-put-contents.php
Update :
assuming that the data is correctly being passed. here is what you can do.
$info = array();
$folder_name = $this->input->post('folder_name');
$info['title'] = $this->input->post('title');
$info['description'] = $this->input->post('description');
$info['code'] = $this->input->post('code');
$json = json_encode($info);
$file = "./videos/overlay.txt";
//using the FILE_APPEND flag to append the content.
file_put_contents ($file, $json, FILE_APPEND);
Update 2:
if you want to access the value back from the text file. overlay.txt here is what you can do
$content = file_get_contents($file);
if you want to fetch title, code, and description separately. and if the string is in json then you need to convert it into array first by using.
//this will convert the json data back to array
$data = json_decode($json);
and to access individual value you can do it like this if you have one row
echo $data['title'];
echo $data['code'];
echo $data['description'];
if you have multiple rows then you can use php foreach loop
foreach($data as $key => $value)
{
$key contains the key for example code, title and description
$value contains the value for the correspnding key
}
hope this helps you.
Update 3:
do it like this
$jsonObjects = file_get_contents('./videos/overlay.txt');
$jsonData = json_decode($jsonObjects);
foreach ($jsonData as $key => $value) {
echo $key . $value;
//$key contains the key (code, title, descriotion) and $value contains its corresponding value
}