For a site I'm working on, a user has the option to input exercise data and it is saved to a JSON file in an array:
{
"Email": "chandlerbing#centralperk.com",
"ExerciseType": "Running",
"DistanceTravelled": "35",
},
But what I want it to do is to be able to save it in a multidimensional array so multiple records can be put in for one user.
Example:
{
"chandlerbing#centralperk.com"
{
"ExerciseType": "Running",
"DistanceTravelled": "35",
}
}
That way multiple records for the user are saved under one primary object to make it easier to access later. However I've never used multi-dimensional arrays before so I can't figure out how to modify my code to get this to work.
// Save data
$file = ('data.json');
$arr = array();
$new_userstats = array (
'Email' => $email,
'ExerciseType' => $exerciseType,
'DistanceTravelled' => $distance
);
$jsondata = file_get_contents($file);
$arr_data = json_decode($jsondata, true);
array_push($arr_data, $new_userstats);
$jsondata = json_encode($arr_data, JSON_PRETTY_PRINT);
file_put_contents($file,$jsondata);
If Email is the attribute to uniquely identify a user. It would be great to keep this as key of our array to easily find
and add a new data to existing file.
Now the format we would be storing in file looks like
{
"chandlerbing#centralperk.com" : [
{
"ExerciseType": "Running",
"DistanceTravelled": "35",
},
{
"ExerciseType": "Jogging",
"DistanceTravelled": "13",
},
],
"test#centralperk.com" : [
{
"ExerciseType": "Running",
"DistanceTravelled": "11",
},
]
}
Now how to add new data to this file would be in following way.
// Fetch existing data
$strFile = 'data.json';
$arrExistingData = json_decode(file_get_contents($strFile), true);
// Add new data to existing data, new data would contain and object in following way
$arrNewData = [
'ExerciseType' => $exerciseType,
'DistanceTravelled' => $distance
];
$arrExistingData[$email][] = $arrNewData;
// Save data back to file, avoid JSON_PRETTY_PRINT to reduce the file size.
file_put_contents($strFile, json_encode($arrExistingData));
Try:
$new_userstats = array (
$email => array (
'ExerciseType' => $exerciseType,
'DistanceTravelled' => $distance
)
);
Related
Hello fellow developers.
In order to create an automatic Drag n 'Drop function in PHP for uploading files, I am stuck in the data update after saving a first file. Indeed, I store in my database a JSON table which contains the name of the file, its path and also its type.
It looks something like this :
{
"1": {
"name": "1",
"path": "/files/project/customer1/pictures/",
"type": "jpeg"
}
}
However, if now I add another file, I can't find a solution to add it following my JSON structure.
I would like it to follow this logic:
{
"1": {
"name": "img1",
"path": "/files/project/customer1/pictures/",
"type": "jpeg"
},
"2": {
"name": "img2",
"path": "/files/project/customer1/pictures/",
"type": "jpeg"
}
}
Here is the condition I made.
I use the MEDOO library in PHP, hence the update function.
The before function retrieves everything after the "." so recover the file type.
<?php
if ($error == "") {
echo $_FILES["$name"]["name"] . " a bien été téléchargé";
$jsonOrig = '';
$jsonOrig = $database->get($table, 'attachment', ['id' => $table_id]);
$database->update(
$table,
['attachment' => Core::jsonify(
$jsonOrig,
['name' => $this->before('.', $_FILES["$name"]["name"]), 'path' => '/files/' . $path . '/', 'type' => $ext],
1
)],
['id' => $table_id]
);
}
The jsonify function allows you to generate JSON automatically.
<?php
public static function jsonify($jsonOrig = array(), $jsonAdd, $where = "")
{
header('Content-Type: application/json');
if (!is_array($jsonOrig)) {
$jsonOrig = json_decode($jsonOrig, true);
}
if (!is_array($jsonAdd)) {
$jsonAdd = json_decode($jsonAdd, true);
}
if (empty($where)) $jsonOrig[] = $jsonAdd;
else $jsonOrig[$where] = $jsonAdd;
return json_encode($jsonOrig, JSON_PRETTY_PRINT);
}
Here is the function once used
// parameter one = input file name
// parameter two = The path where the file will be uploaded
// parameter three = table name database
// parameter four = id where add the json file in the database
$Files->addFile('file', 'projets/client2/photos', 'articles', 54);
Thank you in advance for your help.
The third parameter to Core::jsonify is the "$where", meaning the key behind which you will store your new item in the array. If you pass 1 it will always store the value behind the same key, actually overriding your previously stored item. Remove this parameter and it will properly append to the array (what is done here $jsonOrig[] when key is missing PHP appends a new item).
<?php
if ($error == "") {
echo $_FILES["$name"]["name"] . " a bien été téléchargé";
$jsonOrig = '';
$jsonOrig = $database->get($table, 'attachment', ['id' => $table_id]);
$database->update(
$table,
['attachment' => Core::jsonify(
$jsonOrig,
['name' => $this->before('.', $_FILES["$name"]["name"]), 'path' => '/files/' . $path . '/', 'type' => $ext]
//remove the ",1"
)],
['id' => $table_id]
);
}
If this doesn't work, it means that the get doesn't retreive properly existing data
I'm trying to put a users "favourite" game into the corresponding file for their user upon post.
if(isset($_POST['favourite'])){
$filetxt = 'data/users.json';
$formdata = $_POST['favourite']; //this contains the value "game"
$arr_data = array();
if(file_exists($filetxt)) {
$jsondata = file_get_contents($filetxt);
$arr_data = json_decode($jsondata, true);
}
$arr_data[][$_SESSION['username']]['favourite'] = $formdata;
$jsondata = json_encode($arr_data, JSON_PRETTY_PRINT);
file_put_contents('data/users.json', $jsondata);
}
The file is structured as:
[
{
"CNR": {
"first-name": "test",
"last-name": "test",
"email": "test",
"country": "test",
"password": "test",
"favourite": []
}
},
{
"usertest": {
"first-name": "test",
"last-name": "test",
"email": "test",
"country": "United States",
"password": "password",
"favourite": []
}
}
]
Currently it will add the correct data however not into the array, but onto the end.
[
{
"CNR": {
"first-name": "test",
"last-name": "test",
"email": "test",
"country": "test",
"password": "test",
"favourite": []
}
},
{
"usertest": {
"first-name": "test",
"last-name": "test",
"email": "test",
"country": "United States",
"password": "password",
"favourite": []
}
},
{
"CNR": {
"favourite": "game"
}
}
]
I've tried things like arraypush, splice and other methods however I'm not sure what is the best for this use case.
Any thoughts/recommendations on how I can best achieve this with the desired result are greatly appreciated, thanks!
$arr_data[$_SESSION['username']]['favourite'][] = $formdata;
Difference is that I moved [] to the end of the $arr_data.
Before adding it to array, you need to check if the key exists and then proceed rather than just adding the code.
if(isset($_POST['favourite'])){
$filetxt = 'data/users.json';
$formdata = $_POST['favourite']; //this contains the value "game"
$arr_data = array();
if(file_exists($filetxt)) {
$jsondata = file_get_contents($filetxt);
$arr_data = json_decode($jsondata, true);
}
// changes over here
if(isset($arr_data[$_SESSION['username']])){
if(isset($arr_data[$_SESSION['username']]['favourite'])){
$arr_data[$_SESSION['username']]['favourite'][] = $formdata;
} else {
$arr_data[$_SESSION['username']]['favourite'] = $formdata;
}
} else {
$arr_data[][$_SESSION['username']]['favourite'] = $formdata;
}
$jsondata = json_encode($arr_data, JSON_PRETTY_PRINT);
file_put_contents('data/users.json', $jsondata);
}
I can see that most have answered the question but might I also provide some suggestions (food for thought) on your process?
1). Firstly, I can't work out if you are storing ALL users in a single file or if there's a file per user. Example username.json
I am going to assume there is a file per username because there should be to make file writes quicker and it would require the main file to be locked for everyone else just because one user is writing to it.
2). I noticed that the favourite part seems to be stored in the _SESSION too. If the _SESSION is storing the same mini array in it (a replica of what is stored in the file) then there's no point in opening the file to write a single value and then save it again. You may as well just write over the existing file straight away. Like this...
$writeToFile = json_encode($_SESSION[mydata]);
$fh = fopen("/path/to/username.json","w+");
fwrite($fh,$writeToFile);
fclose($fh);
// You could also use file_put_contents but most prefer
// to use fopen()
3). I will assume the passwords you are storing are encrypted and nobody can type [yourdomain]/users/username.json to see the raw output of the json files. You might want to ensure .json files aren't accessible from the browser. You can do that with .htaccess.
Problem is in this code, you are creating every time a new sub array:
Change this:
$arr_data[][$_SESSION['username']]['favourite'] = $formdata;
To this
if(isset($arr_data[$_SESSION['username']])) {
$arr_data[$_SESSION['username']]['favourite'] = $formdata;
}
I'm messing about with FB Messenger and trying to send a 'list' back, this has to be created with a mySQL lookup and loop.
The correct JSON to send back is defined on Facebook Developers here.
What I cannot understand is how with PHP I create the 'header' and 'footer' of the object, I have made a loop to put the main content into an array using my database results:
$messagePayload = array();
while($row = $result->fetch_assoc()) {
$messagePayloadC = array();
$messagePayloadC['title'] = $row['Name'].";
$messagePayloadC['item_url'] = $row['link'];
$messagePayloadC['image_url'] = $row['Image'];
$messagePayloadC['subtitle'] = "$".$row['Price'].";
$messagePayloadC['buttons']['type'] = "web_url";
$messagePayloadC['buttons']['url'] = $row['link'];
$messagePayloadC['buttons']['title'] = "Go!";
$messagePayload[] = $messagePayloadC;
}
echo var_dump(json_encode($messagePayload))."<p>";
What I need to do is add all of the missing peices at the start and end. The output of my array gives:
{"title":"My Television","item_url":"https:\/\/www.google.com\/","image_url":"product-image.jpg","subtitle":"$5","buttons":{"type":"web_url","url":"https:\/\/www.google.com\/","title":"Go!"}}
The missing header for example is:
"attachment": {
"type": "template",
"payload": {
"template_type": "list",
"top_element_style": "compact",
"elements": [
Am I going about this in the wrong way ?
I have 2 different php files that am using to fetch data from an API and one JSON file for storing the data. I want that when i run each of the PHP files on the server, my Json file would store array from both PHP files. E.g:
store.json
{
"articles": [{
"author": "Rozina Sabur",
"title": "John Cleese to return to new BBC sitcom Edith - despite saying he would never be back",
"description": "Almost 40 years on from his starring role in Fawlty Towers, John Cleese is set to return to the BBC for a new sitcom.",
"url": "http:\/\/www.telegraph.co.uk\/news\/2017\/04\/11\/john-cleese-return-new-bbc-sitcom-edith-despite-saying-would\/",
"publishedAt": "2017-04-11T22:10:11Z"
}]
"players": [
{
"name": "Marcos Alonso",
"position": "Left-Back",
"nationality": "Spain",
"contractUntil": "2021-06-30",
"marketValue": "9,000,000 €"
}]
}
first.php
$url = ('myAPI.com');
$jsondata = file_get_contents($url);
$data = json_decode($jsondata, true);
$values = array();
$resp = array();
$date = date('Y-m-d H:m:s');
//get the employee details
foreach ($data['players'] as $myp) {
$name = $myp['name'];
$posi = $myp['position'];
$nation = $myp['nationality'];
$market = $myp['marketValue'];
$values[] = array('name' => $name, 'position' => $posi, 'nationality' => $nation, 'marketValue' => $market, 'created' => $date);
}
$resp['players'] = $values; //HERE IS THE PART (PLATERS)
$fp = fopen('myJson.json', 'w');
fwrite($fp, json_encode($resp));
fclose($fp);
second.php The code is pretty much like that of first.php just API diff.
.......
........
$values[] = array('author' => $author, 'title' => $title, 'description' => $descrip, 'url' => $ur, 'publishedAt' => $publish);
}
$resp['articles'] = $values; //HERE IS THE MAIN POINT (ARTICLES)
$fp = fopen('myJson.json', 'w');
fwrite($fp, json_encode($resp));
fclose($fp);
My problem is, when I run first.php the array replaces that of second.php and vise versa. How to I fix it so that array from both PHP file store in the JSON file like in the store.php file above.
Other ideas on best practices other than 2 diff php files are welcome.
Thanks
Because both programs are opening the file as 'w'
Change it to this
$fp = fopen('myJson.json','a');
just as a note, this will not be a valid 'single json file', but a file of valid json lines.
$fp = fopen('myJson.json', 'a');
fwrite($fp, json_encode($resp));
fclose($fp);
use a flag to keep last data
Add this method to a PHP file and require this file in your two PHP files.
function storeJson($data, $type)
{
$prevData = file_get_contents('store.json');
$arrayData = json_decode($prevData, true);
if(in_array($type, array_keys($arrayData))) {
$arrayData[$type] = $data;
$fp = fopen('store.json', 'w');
fwrite($fp, json_encode($arrayData));
fclose($fp);
}
}
In first.php file at the end call the method
storeJson($resp, 'players');
In the second.php file
storeJson($resp, 'articles');
I'm reading a json file using
$jsonStr = file_get_contents("connection.json");
$jsonParsed = json_decode($jsonStr,true);
and I want $jsonParsed to be a associative array like this:
$jsonParsed = { "SERVER" => "111.222.333.444" , "USER" => "edvaldo" , "PASSWORD" => "my_password_here", "DATABASE" => "my_database_here" };
What is the format of the JSON needed to do this?
I tried this
{
"SERVER": "111.222.333.444",
"USER": "edvaldo",
"PASSWORD": "my_password_here",
"DATABASE": "my_database_here"
}
but even with JSONLint saying this piece og JSON is valid, I can't get the result I need.
I'm not really very used to JSON and then I will appreciate a lot any help given.
EDITED:
This is the function I'm using:
private function set_mysql_parameters() {
$this->connectionParams = array();
$json_file = $this->system_paths["JSONDATA"] . "connection.json";
$json_mysql = file_get_contents($json_file);
$json_parsed = json_decode($json_file,true,250);
foreach($json_parsed as $key => $value) {
$this->connectionParams[$key] = $value;
}
}
My goal is to fill this array $this->connectionParams with data extracted from the JSON file.
I notice that you are trying to decode the filename instead of the content.
$json_file = $this->system_paths["JSONDATA"] . "connection.json";
$json_parsed = json_decode($json_file,true,250);
Shouldn't it be
$json_parsed = json_decode($json_mysql, true, 250);