Failed to modify JSON file in PHP - php

This is my json.json file content
{
"Title": "Hello World",
"Inputs": [
{
"Id": "1",
"Title": "One"
},
{
"Id": "15",
"Title": "Fifteen"
}
]
}
I am trying to modify it as the follows -
$text = file_get_contents("json.json");
$json = json_decode($text,true);
foreach($json["Inputs"] as $input){
if($input["Id"]== "15"){
$input["Title"] = "This is from me.";
}
}
$new = json_encode($json);
file_put_contents('json.json', $new);
But the file is not being updated.
Any idea?

Your JSON in the example is improperly formatted, but the issue you are having is that you do not set the title in the original array. You change the copy that is passed to the foreach loop.
Change your foreach loop to this and your changes should be shown:
foreach($json["Inputs"] as $key => $input){
if($input["Id"]== "15"){
$json["Inputs"][$key]["Title"] = "This is from me.";
}
}
The foreach loop takes the value by reference, so changing the $json['Inputs'] will change the original value, whereas changing $input modifies the copy that is passed to the loop, and does not change the original json data. There are ways to pass by reference to the foreach loop, but this seems like a simpler solution.

Related

PHP How to properly merge arrays for following json structure

So i tried a lot of possible codes out but i can't seem to find a proper solution.
First let's start with the the wished array (i will show it in a json format as it's easier to read)
{
"transaction": {
"input": [
{
"address": "a",
"value": 4294967295
},
{
"address": "b",
"value": 51515
}
],
"output": [
{
"address": "aa",
"value": 551
},
{
"address": "bb",
"value": 66564
}
]
}
}
I'm using 2 foreach loops to get data that i wanna put in inputs & outputs
Here's the code im using:
//Get Output Addresses & Value
$tmp_array = array();
foreach($json['result']['vout'] as $a)
{
$value = $a['value'];
$address = $a['scriptPubKey']['addresses'][0];
$tmp_array = array('wallet' => $address, 'value' => $value);
$input = array_merge($input, $tmp_array);
};
$input = array('inputs' => $tmp_array);
$input = json_encode($input);
print_r($input);
That's the code for me getting the data and trying to put it into the array. Now i have a problem, it only adds data from the last iteration of the loop. I'm trying to get a code that gets it in a strucuture like above. Whatever solution gets sent, it should be applicable so i can paste the same code in the other loop that is for the outputs
You are assigning the $input variable after the loop with the value of $tmp_array which will be the value from the last iteration, as you described. To fix this you should initialize the $input array as empty array at the beginning and merge that with the new data:
//Get Output Addresses & Value
$inputs = array();
foreach($json['result']['vout'] as $a)
{
$value = $a['value'];
$address = $a['scriptPubKey']['addresses'][0];
$tmp_array = array('wallet' => $address, 'value' => $value);
$inputs[] = $tmp_array; // push to array
};
$input = json_encode(array('inputs' => $inputs));
print_r($input);

JSON Get the name of dynamically changing key with PHP

I am having trouble getting the name of a dynamic key from a JSON string.
I am using PHP
This is a sample of the JSON
{
"_text": "this is a test",
"entities": {
"dynamic_key": [
{
"confidence": 0.99,
"value": "thi is the answer"
}
]
},
"msg_id": "1234532123"
}
I am using foreach to go trough the json key and get the values
foreach ($json as $obj) {
$search_term = $obj->_text;
$msg_id = $obj->msg_id;
}
But I am not sure how to get the value of the "dynamic_key" which changes every time, and because of that I also cannot get the values of "confidence and value" keys.
Any ideas on how to approach this?
Followed #Dimi, solution. This is what I ended up with
$data=json_decode($json,true);
foreach ($data['entities'] as $key=>$val)
{
echo "Entity: $key";
foreach ($data['entities'] as $keys){
$conf = $keys[0]['confidence'];
$answer = $keys[0]['value'];
echo "conf: $conf, answ: $answer";
}
}
Can you provide a couple more examples?
Or try this code and let us know if it breaks
<?php
$json='{
"_text": "this is a test",
"entities": {
"dynamic_key": [
{
"confidence": 0.99,
"value": "thi is the answer"
}
]
},
"msg_id": "1234532123"
}';
$data=json_decode($json,true);
foreach ($data['entities'] as $key=>$val)
{
echo "VALUE IS $key\n values are ";
var_dump($val);
}
Using the data you've shown, there doesn't seem to be an array for the starting JSON.
But with that data the following will use foreach to both fetch the key and the data and then another sub-loop to fetch the confidencevalue...
$search_term = $json->_text;
$msg_id = $json->msg_id;
foreach ( $json->entities as $key => $entities ) {
echo $key.PHP_EOL;
foreach ( $entities as $entity) {
echo $entity->confidence.PHP_EOL;
}
}
If you decode the JSON as an array and if the dynamic key is the only key under entities, then:
$array = json_decode($json, true);
$dynamic = current($array['entities']);
$confidence = $dynamic['confidence'];
$value = $dynamic['value'];
Or shorter:
$confidence = current($array['entities'])['confidence'];
You can probably use reset, current and maybe array_pop etc.

How to extract nested tag from this JSON?

I have the following MediaWiki JSON format.
How would I go about extracting the content of the 'extract' tag, when underneath the pages I have a tag with a page number that keeps changing?
{
"batchcomplete": "",
"warnings": {
"extracts": {
"*": "1"
}
},
"query": {
"pages": {
"2205": {
"pageid": 2205,
"ns": 0,
"title": "Name",
"extract": "Body"
}
}
}
}
Using this code it works:
$json = curl_exec($ch);
$data = json_decode($json,true);
echo $data['query']['pages']['2205']['extract'];
But again, given the page id keeps changing, I can't get it working properly.
I've tried:
echo $data['query']['pages'][0]['extract'];
, but that doesn't work.
You could use reset() to get the first element of an array:
$page = reset($data['query']['pages']);
echo $page['extract']; // Body

How to loop over and access various elements in an array that is both multidimentional and associative? PHP, either JSON or XML

I'm retrieving bibliographic data via an API (zotero.org), and it is similar to the sample at the bottom (just way more convoluted - sample is typed).
I want to retrieve one or more records and display certain values on the page. For example, I would like to loop through each top level record and print the data in a nicely formated citation. Ignoring the proper bib styles for the moment, let's say I want to just print out the following for each record returned:
author1 name, author2 name, article title, publication title, key
This doesn't match the code, because I've clearly been referencing the key value pairs incorrectly and will just make a mess of it.
The following is laid out like the data if I request JSON format, though I can request XML data instead. I'm not picky; I've tried using each with no luck.
[
{
"key": "123456",
"state": 100,
"data": {
"articleTitle": "Wombat coprogenetics: enumerating a common wombat population by microsatellite analysis of faecal DNA",
"authors": [
{
"firstName": "Sam C.",
"lastName": "Smith"
},
{
"firstName": "Maxine P.",
"lastName": "Jones"
}
],
"pubTitle": "Australian Journal of Zoology",
"tags": [
{
"tag": "scary"
},
{
"tag": "secret rulers of the world"
}
]
}
},
{
"key": "001122",
"state": 100,
"data": {
"articleTitle": "WOMBAT and WOMBAT-PK: Bioactivity Databases for Lead and Drug Discovery",
"authors": [
{
"firstName": "Marius",
"lastName": "Damstra"
}
],
"pubTitle": "Chemical Biology: From Small Molecules to Systems Biology",
"tags": [
{
"tag": "Wrong Wombat"
}
]
}
}
]
If there is a mistake in brackets, commas, etc. it is just a typo in my example and not the cause of my issue.
decode your json as array and iterate it as any array as flowing:
$json_decoded= json_decode($json,true);
$tab="\t";
foreach ($json_decoded as $key => $val) {
echo "Article ".$val["key"]."\n" ;
echo $tab."Authors :\n";
foreach ($val["data"]["authors"] as $key => $author){
echo $tab.$tab. ($key+1) ." - ".$author["firstName"]. " ".$author["lastName"]."\n";
}
echo $tab."Article Title: ".$val["data"]["articleTitle"] ."\n";
echo $tab."Publication Title: ".$val["data"]["pubTitle"] ."\n";
echo $tab."Key: ".$val["key"]."\n";
}
run on codepad
and you can use the same method for xml as flowing:
$xml = simplexml_load_string($xmlstring);
$json = json_encode($xml);
$json_decoded = json_decode($json,TRUE);
//the rest is same
for xml you can use the SimpleXml's functions
or DOMDocument class
Tip
to know the structure of your data that api return to you after it converted to array use var_dump($your_decoded_json) in debuging
Something like this might be a good start for you:
$output = [];
// Loop through each entry
foreach ($data as $row) {
// Get the "data" block
$entry = $row['data'];
// Start your temporary array
$each = [
'article title' => $entry['articleTitle'],
'publication title' => $entry['pubTitle'],
'key' => $row['key']
];
// Get each author's name
foreach ($entry['authors'] as $i => $author) {
$each['author' . ++$i . ' name'] = $author['firstName'] . ' ' . $author['lastName'];
}
// Append it to your output array
$output[] = $each;
}
print_r($output);
Example: https://eval.in/369313
Have you tried to use array_map ?
That would be something like:
$entries = json_decode($json, true);
print_r(array_map(function ($entry) {
return implode(', ', array_map(function ($author) {
return $author['firstName'];
}, $entry['data']['authors'])) . ', ' . $entry['data']['articleTitle'] . ', ' . $entry['key'];
}, $entries));

Overwrite a json after modification in PHP

I make a modification in my json with this code:
$id = "hotel_name";
$value ="My Hotel";
$json = json_decode(file_get_contents('datas.json'));
$datas = $json->datas;
foreach ($datas as $category => $data) {
foreach ($data as $element) {
if($element->id==$id) {
$datas->$category->$element->$id = $value;
}
}
}
$newJson = json_encode($element);
file_put_contents('datas.json', $newJson);
But it do not put all the content in it.
How to solve it please ?
My json has the following:
{
"datas": {
"General": [
{
"field": "hotel_name",
"name": "My Hotel name"
}
]
}
}
You are accessing the $element variable, which contains only your inner most data
{
"field": "hotel_name",
"name": "My Hotel name"
}
If you want more of your data, you will have to reassign your outermost $datas variable and children with the newly updated $element variable. I'd recommend creating an empty variable to store the new data instead of altering the original copy.
You should be encoding datas, not just the last element, right?
// before
$newJson = json_encode($element);
// after
$newJson = json_encode($datas);
By the way, you might find it easier to work with the data if you convert it to an array rather than object.
$json = json_decode(file_get_contents('datas.json'), true);

Categories