PHP update json from received input and write back to same file - php

I have a json file stored on server & it looks like below:
{
"support_link":"#",
"support_link_2":"#",
"packs":[
{
"identifier":1,
"viewCount":0,
"downloadCount":0
},
{
"identifier":2,
"viewCount":0,
"downloadCount":0
}
]
}
By using PHP, I want to update the viewCount & downloadCount of some of the arrays inside packs.
But the thing is the data is received via a POST method to the server which contains another json with info. of which identifier to update & what param to update, & I am not able to update the existing file & save it back.
Received Json format:
{
"impressions": [
{
"identifier": "1",
"impressionCount": 2
},
{
"identifier": "100",
"impressionCount": 2
},
{
"identifier": "1000",
"impressionCount": 2000
}
],
"downloads": [
{
"identifier": "1",
"downloadCount": 10
}
]
}
What I've tried to do so far:
$json = file_get_contents('php://input');
if ($json != '') {
$properJsonFormatted = json_decode($json, true);
$impressions = $properJsonFormatted['impressions'];
$downloads = $properJsonFormatted['downloads'];
$testConfig =
$json = file_get_contents('php://input');
if ($json != '') {
$properJsonFormatted = json_decode($json, true);
$impressions = $properJsonFormatted['impressions'];
$downloads = $properJsonFormatted['downloads'];
$testConfig = json_decode(file_get_contents("test_config.json"),true);
$packs = $testConfig['packs'];
foreach ($packs as &$pack) {
$packIdentifier = $pack['identifier'];
foreach ($impressions as $impression) {
$impressionIdentifier = $impression['identifier'];
if ($packIdentifier == $impressionIdentifier) {
$pack['viewCount'] += $impression['impressionCount'];
$newCount = $pack['viewCount'];
print("Id: $packIdentifier, ViewCount: $newCount\n");
}
}
}
put_file_contents("test_config.json" , $testConfig);
// print_r($testConfig);
// Save back the updated test_config.json
}
}

UPDATE
Seem to have misinterpreted the question. The actual problem seems to be much simpler.
Change this:
put_file_contents("test_config.json" , $testConfig);
To this:
file_put_contents('test_config.json', json_encode($testConfig));
Also change this:
$packs = $testConfig['packs'];
To this:
$packs = &$testConfig['packs'];
As it seems you forgot to assign that by reference, while you correctly did that in the foreach.

Related

JSON update in PHP : duplication

I have a strange issue when I'm trying to update a json in my database.
This is my code :
// Update content of user cart
$contentJSON = json_decode($userCart['content'],true);
$newJSONContent;
$wineNotExist = true;
$index = 1;
foreach($contentJSON as $key) {
// Update content if wine is already in user cart
if ($key['wineId'] === $wineId) {
$contentObject->wineId = $wineId;
$contentObject->wineQuantity = $key['wineQuantity'] + $wineQuantity;
$dataIndex = strval($index);
$newJSONContent->$dataIndex = $contentObject;
$wineNotExist = false;
} else {
$contentObject->wineId = $key['wineId'];
$contentObject->wineQuantity = $key['wineQuantity'];
$dataIndex = strval($index);
$newJSONContent->$dataIndex = $contentObject;
}
$index++;
}
if ($wineNotExist) {
$dataKey = strval($index);
$contentObject->wineId = $wineId;
$contentObject->wineQuantity = $wineQuantity;
$newJSONContent->$dataKey = $contentObject;
}
So, I decided to build a new JSON and parse the former; moreover if json not contains the wineId we created a new data input in JSON but this section replaces previous key by the right one and create the right one as you can see in AJAX response here :
Response when it's the same wineId
{
"code": 200,
"status": "success",
"message": "This wine has been added to your cart",
"content": {
"1": {
"wineId": 2,
"wineQuantity": 3
}
},
"index": true
}
Response when wineId is not contains in cart
{
"code": 200,
"status": "success",
"message": "This wine has been added to your cart",
"content": {
"1": {
"wineId": 5,
"wineQuantity": 1
},
"2": {
"wineId": 5,
"wineQuantity": 1
}
},
"index": true
}
I don't understand why the instruction in if replaces previous value, do you have an idea why ?
When I use another variable name for contentObject in if instruction, the code works but why ? Because $contentObject is a local variable in foreach loop
Sorry for my english, I'm French.
It works with this code, so the problem is that $contentObject has the previous value whereas it's a local varibale, is it specific to PHP ?
// Update content of user cart
$contentJSON = json_decode($userCart['content'],true);
$newJSONContent;
$wineNotExist = true;
$index = 1;
foreach($contentJSON as $key) {
// Update content if wine is already in user cart
if ($key['wineId'] === $wineId) {
$contentObject=null;
$contentObject->wineId = $wineId;
$contentObject->wineQuantity = $key['wineQuantity'] + $wineQuantity;
$dataIndex = strval($index);
$newJSONContent->$dataIndex = $contentObject;
$wineNotExist = false;
} else {
$contentObject=null;
$contentObject->wineId = $key['wineId'];
$contentObject->wineQuantity = $key['wineQuantity'];
$dataIndex = strval($index);
$newJSONContent->$dataIndex = $contentObject;
}
$index++;
}
if ($wineNotExist) {
$contentObject=null;
$dataKey = strval($index);
$contentObject->wineId = $wineId;
$contentObject->wineQuantity = $wineQuantity;
$newJSONContent->$dataKey = $contentObject;
}

How to parse json array from mysql?

I have this data but I can't parse it in the way I want. this is what I get:
{
"navigations": {
"title": "Facebook",
"link": "https://facebook.com",
"behavior": "EXTERNAL"
}
}
And what I expect to see:
{
"navigations": [
{
"title": "Facebook",
"url": "https://facebook.com",
"behavior": "INAPP"
},
{
"title": "Youtube",
"url": "https//youtube.com",
"behavior": "INAPP"
}
]
}
I have more results in my database but not more than 12 result so, i want to fetch data in the format i expect. I tried to do it using fetch_array but no success.
This is my PHP code:
$query_update_navigations = $db->prepare("SELECT title, link, behavior FROM navigation_tabs WHERE secret_api_key=?");
$query_update_navigations->bind_param("s", $_SESSION['secret_api_key']);
$query_update_navigations->execute();
$rows = array();
$result = $query_update_navigations->get_result();
while($rows1 = $result->fetch_assoc()) {
$rows['navigations'] = $rows1;
}
$store_path = '../apis/navigation_tabs/';
$file_name = $_SESSION['secret_api_key'] . '.json';
$sign_constants = json_encode($rows);
file_put_contents($store_path . $file_name, $sign_constants);
I searched for an answer but nothing solved my issue :(
You need to push the row onto the array, not overwrite it each time.
$rows = array('navigations' => []);
$result = $query_update_navigations->get_result();
while($rows1 = $result->fetch_assoc()) {
$rows['navigations'][] = $rows1;
}

how to get json key name from the result in php?

I want to the key or reference_id detail (as both are same value) when the art_ean value contains 400004471.
{
"TD0000000000993": {
"reference_id": "TD0000000000993",
"art_ean": "400004481|,400004491|,400004471|"
},
"TD0000000000992": {
"reference_id": "TD0000000000992",
"art_ean": "400004482|,400004492|,400004472|"
}
}
Your json is not valid. You should remove the last , on each object. You can use a list to have some more details https://jsonlint.com.
Here is what I believe that you want.
<?php
$data = '{
"TD0000000000993": {
"reference_id": "TD0000000000993",
"art_ean": "400004481|,400004491|,400004471|"
},
"TD0000000000992": {
"reference_id": "TD0000000000992",
"art_ean": "400004482|,400004492|,400004472|"
}
}';
$decodedData = \json_decode($data, true);
$result = array_column(
array_filter($decodedData, function($data) {
return false !== strpos($data['art_ean'], '400004471');
}),
'reference_id'
);

Generate JSON response on server with JsonArray and single fields

I am trying to build a JSON response from my server side, but it is not working as expected.
It is probably something simple but, I am not so good at PHP...
The basic expected response is a JSON with a single JsonArray and some other fields, for that, the relevant piece of code is shown here:
Sample of expected JSON response:
{
"pageNr": 2
"totalPages":28
"products":[
{
"user_name":"testUser001",
"product_ID":"4756373abdhg"
},
{
"user_name":"testUser002",
"product_ID":"475ggdfghghg"
},
{
"user_name":"testUser003",
"product_ID":"47466gdgbdhg"
},
{
"user_name":"testUser004",
"product_ID":"4000nfaergeb"
},
{
"user_name":"testUser005",
"product_ID":"adfer73abdhg"
}
]
}
Basic PHP code used to generate desired JSON (among sql query and other things):
$res = array();
$res2 = array();
while($r = mysqli_fetch_assoc($query2)) {
$res["user_name"] = $r["user_name"];
$res["product_ID"] = $r["prod_ID"];
array_push($res2,$res);
}
$response = ['pageNr' => $page];
$response = ['totalPages' => $totalPages];
$response = ['products' => $res2];
Response that this code is generating on Postman:
{
"products":[
{
"user_name":"testUser001",
"product_ID":"4756373abdhg"
},
{
"user_name":"testUser002",
"product_ID":"475ggdfghghg"
},
{
"user_name":"testUser003",
"product_ID":"47466gdgbdhg"
},
{
"user_name":"testUser004",
"product_ID":"4000nfaergeb"
},
{
"user_name":"testUser005",
"product_ID":"adfer73abdhg"
}
]
}
So, for some reason the JSON response is not accepting more fields pageNrand totalPages.
What is wrong here?.
Each assignment overwrites your array. You need to update it instead:
$res = array();
$res2 = array();
while($r = mysqli_fetch_assoc($query2)) {
$res["user_name"] = $r["user_name"];
$res["product_ID"] = $r["prod_ID"];
array_push($res2,$res);
}
$response = [];
$response['pageNr'] = $page;
$response['totalPages'] = $totalPages;
$response['products'] = $res2;
Try;
$res = array();
$res2 = array();
while($r = mysqli_fetch_assoc($query2)) {
$res["user_name"] = $r["user_name"];
$res["product_ID"] = $r["prod_ID"];
array_push($res2,$res);
}
$response .= ['pageNr' => $page];
$response .= ['totalPages' => $totalPages];
$response .= ['products' => $res2];

Multiple MySQL table to json_encode

I have 3 different tables in my database called consoleConsole, consoleModel, and consoleGame. Then what I want to do is that each console will have a loop inside for its models, and each models will have another loop inside for its games like this:
[
{
"Console":"PlayStation",
"Information":[
{
"Model":"PlayStation 3",
"Title":[
{
"Game":"007 Legends",
"Publisher":"Electronic Arts"
},
{
"Game":"Ace Combat: Assault Horizon",
"Publisher":"Namco"
}
]
},
{
"Model":"PlayStation 2",
"Title":[
{
"Game":"007: Agent of Fire",
"Publisher":"Electronic Arts"
},
{
"Game":"Ace Combat 4: Shattered Skies",
"Publisher":"Namco"
}
]
},
{
"Model":"PlayStation 1",
"Title":[
{
"Game":"007 Racing",
"Publisher":"Electronic Arts"
},
{
"Game":"Ace Combat",
"Publisher":"Namco"
}
]
}
]
},
{
"Console":"Wii",
"Information":[
{
"Model":"Wii",
"Title":[
{
"Game":"007: Quantum of Solace",
"Publisher":"Activision"
},
{
"Game":"AC/DC Live: Rock Band Track Rack",
"Publisher":"MTV Games"
}
]
}
]
},
{
"Console":"Xbox",
"Information":[
{
"Model":"Xbox",
"Title":[
{
"Game":"AFL",
"Publisher":"Acclaim"
},
{
"Game":"American Chopper",
"Publisher":"Activision"
}
]
},
{
"Model":"Xbox 360",
"Title":[
{
"Game":"AFL Live",
"Publisher":"Electronic Arts"
},
{
"Game":"Akai Katana Shin",
"Publisher":"Cave"
}
]
}
]
}
]
But sadly, I was not using my database with this one but instead I just wrote it straight in a php file.
EDIT
Anyways, moving on. I have modified my code and ended up like this.
<?PHP
$consoleQuery = "SELECT * ".
"FROM consoleConsole ".
"JOIN consoleModel ".
"ON consoleConsole.consoleId = consoleModel.consoleId ".
"JOIN consoleGame ".
"ON consoleModel.modelId = consoleGame.gameId";
$consoleResult = mysql_query($consoleQuery);
$consoleFields = array_fill_keys(array(
'consoleName',
), null);
$modelFields = array_fill_keys(array(
'modelName',
), null);
$console = array();
$rowConsole = array();
while ($rowConsole = mysql_fetch_assoc($consoleResult)) {
$consoleId = $rowConsole['consoleId'];
$modelId = $row['modelId'];
if (isset($console[$consoleId]['Information'])) {
$console[$consoleId]['Information'][] = array_intersect_key($rowConsole, $modelFields);
}
else {
$console[$consoleId] = array_intersect_key($rowConsole, $consoleFields);
$console[$consoleId]['Information'] = array(array_intersect_key($rowConsole, $modelFields));
}
}
$console = array_values($console);
echo json_encode($console);
?>
I was able to produce an output but it doesn't look like the output above.
[
{
"consoleName": "PlayStation",
"Information": [
{
"modelName": "PlayStation"
},
{
"modelName": "PlayStation 2"
},
{
"modelName": "PlayStation 3"
},
{
"modelName": "PlayStation 3"
}
]
},
{
"consoleName": "Wii",
"Information": [
{
"modelName": "Wii"
},
{
"modelName": "Wii"
}
]
},
{
"consoleName": "Xbox",
"Information": [
{
"modelName": "Xbox"
},
{
"modelName": "Xbox 360"
}
]
}
]
Their relations:
What my problem is right now, I can't add the Title of the each Game.
Ok so I have written up your solution. You have to be sure that the order by is included there because it assumes that you are ordering them with there items together. I also didnt know how your publisher was stored so I separated that out into a separate table (this will allow you to then get items by just there publisher as well), which is now 4 joins. Also on another note I have updated it to do inner joins as well. This way you will not get empty results for consoles that don't have any games assigned to them. If you want these you could simply change the joins so that it would give you those results as well. Let me know if this helps
//get all of the information
$query = '
SELECT c.consoleId,c.consoleName,m.modelId,m.modelName,g.gameId,g.gameName,p.publisherId,p.publisherName
FROM `consoleconsole` c
INNER JOIN `consolemodel` m ON c.consoleId=m.consoleId
INNER JOIN `consolegame` g ON m.modelId=g.modelId
INNER JOIN `consolepublisher` p ON g.publisherId = p.publisherId
ORDER BY c.consoleName, m.modelName, g.gameName
';
//get the results
$result = mysql_query($query);
//setup array to hold information
$consoles = array();
//setup holders for the different types so that we can filter out the data
$consoleId = 0;
$modelId = 0;
//setup to hold our current index
$consoleIndex = -1;
$modelIndex = -1;
//go through the rows
while($row = mysql_fetch_assoc($result)){
if($consoleId != $row['consoleId']){
$consoleIndex++;
$modelIndex = -1;
$consoleId = $row['consoleId'];
//add the console
$consoles[$consoleIndex]['console'] = $row['consoleName'];
//setup the information array
$consoles[$consoleIndex]['information'] = array();
}
if($modelId != $row['modelId']){
$modelIndex++;
$modelId = $row['modelId'];
//add the model to the console
$consoles[$consoleIndex]['information'][$modelIndex]['model'] = $row['modelName'];
//setup the title array
$consoles[$consoleIndex]['information'][$modelIndex]['title'] = array();
}
//add the game to the current console and model
$consoles[$consoleIndex]['information'][$modelIndex]['title'][] = array(
'game' => $row['gameName'],
'publisher' => $row['publisherName']
);
}
echo json_encode($consoles);
Since you are using php function to encode json , it will give you the json in its default format. what you have to do is create your own function using string manipulation to get desired result.

Categories