I have json file which contains multiple json objects.
Example
{"t":"abc-1","d":"2017-12-29 12:42:53"}
{"t":"abc-2","d":"2017-12-29 12:43:05"}
{"t":"abc-3","d":"2017-12-30 14:42:09"}
{"t":"code-4","d":"2017-12-30 14:42:20"}
Want to read this file and store into database, but I couldn't convert json to php array which further I can store into database.
I tried json_decode function, but its not working. I search for this but in every link its showing use json_decode. Below is my code
$filename = "folder/filename.json";
$data = file_get_contents($filename);
echo $data;
$tags = json_decode($data, true);
echo"<pre>";print_r($tags);exit;
$data is echoed but not the $tags.
Thanks in advance.
Make array of objects and use it later
$j = array_map('json_decode', file('php://stdin'));
print_r($j);
demo
If it's only four lines you can explode and json_decode each line and add it to an array.
$s = '{"t":"abc-1","d":"2017-12-29 12:42:53"}
{"t":"abc-2","d":"2017-12-29 12:43:05"}
{"t":"abc-3","d":"2017-12-30 14:42:09"}
{"t":"code-4","d":"2017-12-30 14:42:20"}';
$arr = explode(PHP_EOL, $s);
Foreach($arr as $line){
$json[] = json_decode($line,true);
}
Var_dump($json);
https://3v4l.org/97m0E
Multiple objects in a row should be enclosed in a json array and separated with comma like elements.So you need a [ ] at the start and end of the file.Also you could close the pre tag
Either you should fix the file generating that 'json' or you can use fgets to get one line at a time, and use json decode on every line
As pointed by other, JSON which you shared isn't valid. And, I think, it is stored in your file in same fashion. I would suggest to read this file line by line each line then you can decode.
$handle = fopen("folder/filename.json", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
$tags = json_decode($line, true);
echo"<pre>";print_r($tags);exit;
}
fclose($handle);
} else {
// error opening the file.
}
Assuming a file called `filename.json` contains the following lines
{"t":"abc-1","d":"2017-12-29 12:42:53"}
{"t":"abc-2","d":"2017-12-29 12:43:05"}
{"t":"abc-3","d":"2017-12-30 14:42:09"}
{"t":"code-4","d":"2017-12-30 14:42:20"}
So each one is a separate json entity
$filename = "folder/filename.json";
$lines=file( $filename );
foreach( $lines as $line ){
$obj=json_decode( $line );
$t=$obj->t;
$d=$obj->d;
/* do something with constituent pieces */
echo $d,$t,'<br />';
}
Your JSON is invalid, as it has multiple root elements
Fixing it like the following should work (note the [, ] and commas):
[
{"t":"abc-1","d":"2017-12-29 12:42:53"},
{"t":"abc-2","d":"2017-12-29 12:43:05"},
{"t":"abc-3","d":"2017-12-30 14:42:09"},
{"t":"code-4","d":"2017-12-30 14:42:20"}
]
If you cannot influence how the JSON file is created, you will need to create your own reader, as PHP is not built to support invalid formatting. You could separate the file by new lines and parse each one individually.
Related
I have a csv file that looks something like this (there are many more rows):
Jim,jim#email.com,8882,456
Bob,bob#email.com,8882,343
What I want to do is to change all the values in the fourth column,456,343 to 500.
I'm new to php and am not sure how to do this.
I have tried
<?php
$file = fopen('myfile.csv', 'r+');
$toBoot = array();
while ($data = fgetcsv($file)) {
echo $data[3];
$data[3] = str_replace($data[3],'500');
array_push($toBoot, $data);
}
//print_r($toBoot);
echo $toBoot[0][3];
fputcsv($file, $toBoot);
fclose($file)
?>
But it prints
Jim,jim#email.com,8882,456
Bob,bob#email.com,8882,343
Array,Array
not
Jim,jim#email.com,8882,500
Bob,bob#email.com,8882,500
I've looked at this post, PHP replace data only in one column of csv but it doesn't seem to work.
Any help appreciated. Thanks
You can use preg_replace and replace all values at once and not loop each line of the CSV file.
Two lines of code is all that is needed.
$csv = file_get_contents($path);
file_put_contents($path, preg_replace("/(.*),\d+/", "$1,500", $csv));
Where $path is the path and to the CSV file.
You can see it in action here: https://3v4l.org/Mc3Pm
A quick and dirty way to way to solve your problem would be:
foreach (file("old_file.csv") as $line)
{
$new_line = preg_replace('/^(.*),[\d]+/', "$1,500", $line);
file_put_contents("new_file.csv", $new_line, FILE_APPEND);
}
To change one field of the CSV, just assign to that array element, you don't need to use any kind of replace function.
$data[3] = "500";
fputcsv() is used to write one line to a CSV file, not the entire file at once. You need to call it in a loop. You also need to go back to the beginning of the file and remove the old contents.
fseek($file, 0);
ftruncate($file, 0);
foreach ($toBoot as $row) {
fputcsv($file, $row);
}
I am trying to make a PHP script that reads each row of a .csv file. I want to treat each row as an array of data. Please suggest how I can achieve the above?
Use the function fgetcsv().
// Read the first line, headers
$headers = fgetcsv($file);
// Now $headers is an array of your headers
// Read the lines one by one
while (false != ($line = fgetcsv($file))) {
// $line is an array of your cells
}
You could use the following to create an array from the csv;
$aArray = str_getcsv ( file_get_contents("/path/to/file.csv") , ',', '"', "\\");
var_dump($aArray);
Have a read of the PHP manual;
str_getcsv() and file_get_contents()
You can use following to read row from csv file and create array from the csv file:
<?php
$file = fopen("/path/to/file.csv","r");
$arrayCsv = array();
while(!feof($file)) {
$fpTotal = fgetcsv($file);
array_push($arrayCsv,$fpTotal);
}
fclose($file);
print_r($arrayCsv); //prints array from csv
?>
You can use the fgetcsv function to read data from a csv file. Please, look at this :
http://php.net/manual/en/function.fgetcsv.php
Working on a website and need to store data for each user. Currently using json files and the way it is set up currently it overwrites the data each time.
1st question, is using one json file the best way to house this data or should I set up a directory for each user?
2nd question, if one file is the best way to go, how do I append 'unique' data? I found some example code from the posts on "Overwrite JSON if fields match PHP" but it is not working for me. It is not writing to the file at all now.
Original code:
$posts[] = array('vhclID'=> $vhclID, 'statVal1'=> $engStat, 'statVal2'=> $brakeStat);
$response['posts'] = $posts;
$fp = fopen('results.json', 'w');
fwrite($fp, json_encode($response));
fclose($fp);
Revised code to be able to append new data and eliminate redundancies(Does not work):
$file = file_get_contents('results.json');
$data = json_decode($file);
unset($file);//prevent memory leaks for large json.
//insert data here
$data[vhclID] = array('vhclID'=> $vhclID, 'statVal1'=> $engStat,
'statVal2'=> $brakeStat);
//save the file
$data = array_values($data);
file_put_contents('results.json',json_encode($data));
echo json_encode($data);
unset($data);//release memory
Thanks for your help!!
You should use a database if you're storing typical user data; clearly you don't want to load megabytes of user data just to observer or modify one field for one user.
If you have some posted data, and I understand your question correctly, you might do something like this (but add more security):
$new_data = $_POST[];
foreach ($new_data as $name=>$datum) {
if (empty($data[vhclID][$name]) {
// This means that this field is unique
$data[vhclID][$name] = $datum;
}
}
And then just save that data to your JSON file.
$fp = fopen('results.json', 'r');
$postjson = json_decode(fread($fp, 1024*1024), true);
fclose($fp);
$posts = ($posts==array()) array('vhclID'=> $vhclID, 'statVal1'=> $engStat, 'statVal2'=> $brakeStat) : $postjson['posts'];
$response['posts'] = $posts;
$fp = fopen('results.json', 'w');
fwrite($fp, json_encode($response));
fclose($fp);
Should do what you want.
Modify $posts.
I mess around with PHP and json data a lot.
One thing I've noticed is that json_decode will create a PHP object(stdClass) by default
Example
Contents of results.json >>> {"example":"test"}
$file = file_get_contents("results.json");
$json = json_decode($file);
var_dump($json); // Outputs: object(stdClass)#14 (1) { ["example"]=> string(4) "test" }
If you add true as the second parameter to json_decode you end up with an array instead
Example
$file = file_get_contents("results.json");
$json = json_decode($file, TRUE); // Added TRUE as second parameter
var_dump($json); // Outputs: array(1) { ["example"]=> string(4) "test" }
Once you have your appropriate data, you can modify and change the $json however you want and then re-write it to the .json file.
So for question 1: Having an individual json file for each user (eg: userID-001.json, userID-002.json) is probably the better way to go.
For question 2: You can take the individual file, grab the contents and store it in a PHP array using json_decode($data, TRUE) // with true as second parameter if you want an array and then modify the array and resave it (using json_encode).
Hope this helps~!
Here is a JSON data example saved in a file data.txt
[
{"name":"yekky"},
{"name":"mussie"},
{"name":"jessecasicas"}
...// many rows
]
I would like to update the file so it will look like this:
[
{"name":"yekky","num":"1"},
{"name":"mussie","num":"2"},
{"name":"jessecasicas","num":"3"}
...// many rows
]
This is what I have got so far:
$json_data = file_get_contents('data.txt');
// What goes here?
And how do I count how many rows there are in the JSON tree?
Use json_decode() to decode the JSON data in a PHP array, manipulate the PHP array, then re-encode the data with json_encode().
For example:
$json_data = json_decode(file_get_contents('data.txt'), true);
for ($i = 0, $len = count($json_data); $i < $len; ++$i) {
$json_data[$i]['num'] = (string) ($i + 1);
}
file_put_contents('data.txt', json_encode($json_data));
You should use the PHP JSON library for such tasks. For example, after having read your JSON data from the file, do something like:
$json = json_decode($json_data);
$itemCount = count($json);
After having modified your JSON data, just encode it again:
$json_data = json_encode($json);
Also, you seem to want to beatify your JSON data. My advise is to just use whatever comes out of json_encode and save that to your file, because it will probably be the smallest (in file size) possible representation of your JSON data.
If you format it in a way readable for humans, you've got lots of extra spaces / tabs / line-breaks which increase file size and parsing time.
If you need to read it yourself, you can still beautify your JSON data by hand.
$file = 'data.txt';
$data = json_decode(file_get_contents($file));
foreach ($data as $key => $obj) {
$obj->num = (string)($key+1);
}
file_put_contents($file, json_encode($data));
I'm creating a script that will read a csv file and display it on a textarea using fgetcsv.
$handle = #fopen($filePath, "r");
if ($handle)
{
while (($buffer = fgetcsv($handle, 1000,",")) !== false)
{
foreach($buffer as $buff){
echo $buff."\n";
}
}
}
The format of the csv is
"line1-content1","line1-content2"
"line2-content1","line2-content2"
Using fgetcsv, the content will display inside the textarea without double-quote and comma. Can I format it so that it will also display the duoble quotes and comma?
Then upon saving it using fputcsv
$file_to_load = $_GET['filepath'];
$filePath = $dir.$file_to_load;
$trans = trim($_POST['txtarea']);
$keyarr = split("\n",$trans);
$fp = fopen($filePath, 'w');
foreach (array ($keyarr) as $fields) {
fputcsv($fp, $fields);
}
fclose($fp);
Looking on the csv file, it saved the csv but displays it like this
"line1-content1
","line1-content2
","line2-content1
","line2-content2"
It separates the "line1-content1" and "line1-content2" into two lines and put a comma after the end of every line.
Now I want to keep the formatting of #2. How will I code it?
Can you guide me into the right direction? Thanks!
Sounds like you want to display the actual raw CSV text, not the parsed data within the CSV. Instead of using fgetcsv(), just use fgets() and you'll get the text line without any parsing, preserving the quotes and commas.
As for fputcsv, it's going to write out what you pass into it, so make sure that whatever's coming back from the form is cleaned up (e.g. extra line breaks stripped out).