PHP How to properly merge arrays for following json structure - php

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);

Related

How to make multiple records in array php

From my database i am receaving array, that i`m later sending using Fetch Api to my frontend and display data that was send. It looks like this:
return $stmt->fetchAll(PDO::FETCH_NAMED);
and the given output in JSON is like this:
[
{
"name": [
" name1",
" name2",
" name3"
],
"date": "2022-02-05 12:00:00",
"round": "3",
"coordinate x": "number",
"coordinate y": "number",
"leauge_id": 4
}, etc.
What i want to do is to replace fields coordinate x, coordinate y and insert into this array new field location(based on GoogleGeocodeAPI i will transofrm coordinates into location name) and insert it into this array so i will later be able to display this location.
Here is what i tried to do:
$matches = $stmt->fetchAll(PDO::FETCH_NAMED);
foreach ($matches as $match){
$result['nameA'] = $match['name'][0];
$result['nameB'] = $match['name'][1];
$result['nameC'] = $match['name'][2];
$result['date'] = $match['date'];
$result['round'] = $match['round'];
$result['leauge_id'] = $match['leauge_id'];
$result['location']= $this->reverse_geocode($match['coordinate x'],$match['coordinate y']);
}
return $result;
Output from JSON:
{
"nameA": " name",
"nameB": " name",
"nameC": " name",
"date": "2022-02-05 12:00:00",
"round": "29",
"leauge_id": 6,
"location": "location"
}
But it ends up that i`m kinda overwriting the posistion and in the end i am sending only one, the last record. How can i make this work?
$matches = $stmt->fetchAll(PDO::FETCH_NAMED);
foreach ($matches as $match){
$result[] = [
'nameA' => $match['name'][0],
'nameB' => $match['name'][1],
'nameC' => $match['name'][2],
'date' => $match['date'],
'round' => $match['round'],
'leauge_id' => $match['leauge_id'],
'location' => $this->reverse_geocode($match['coordinate x'],$match['coordinate y']),
];
}
return $result;
One way to do this is to create a variable $i and use that to key your array...
<?php
$matches = $stmt->fetchAll(PDO::FETCH_NAMED);
$i=0;
foreach ($matches as $match){
$result[$i]['nameA'] = $match['name'][0];
$result[$i]['nameB'] = $match['name'][1];
$result[$i]['nameC'] = $match['name'][2];
$result[$i]['date'] = $match['date'];
$result[$i]['round'] = $match['round'];
$result[$i]['leauge_id'] = $match['leauge_id'];
$result[$i]['location']= $this->reverse_geocode($match['coordinate x'],$match['coordinate y']);
$i++;
}
return $result;

Struggling to convert to json string

I've got a textbox that the user can enter details into it in a csv format. So they would enter something like
user 1,user1#email.com
user 2,user2#email.com
user 3,user3#email.com
The out put of that when I dd(request('users')) is this
user 1, user1#email.com\n
user 2, user2#email.com\n
user 3, user3#email.com
What I would like is to save it in a json format so that it can end up looking like this
[
{
"name": "user 1",
"email": "user1#email.com"
},
{
"name": "user 2",
"email": "user2#email.com"
},
{
"name": "user 3",
"email": "user3#email.com"
}
]
I'm struggling to get it to be like how I would like it. I've tried json_encode(request('users')) but I ended up with
""user 1, user1#email.com\nuser 2, user2#email.com\nuser 3, user3#email.com""
I also tried this
$replace = preg_replace('/\n+/', "\n", trim(request('users')));
$split = explode("\n",$replace);
$json = json_encode($split);
but I got this
"["user 1, user1#email.com","user 2, user2#email.com", "user 3, user3#email.com"]"
The keys name and email you want in your result are not going to appear out of thin air, you need to create them.
Split the data into individual lines, loop over those lines.
Split each line into its two parts.
Create the necessary data structure, introduce the keys you want the data to be stored under at this point.
Encode the whole thing as JSON.
$data = 'user 1,user1#email.com
user 2,user2#email.com
user 3,user3#email.com';
$lines = explode("\n", $data);
$result = [];
foreach($lines as $line) {
$parts = explode(',', $line);
$result[] = ['name' => $parts[0], 'email' => $parts[1]];
}
echo json_encode($result);
You can simply use array_map to map each line to a key-value pair created by using array_combine:
$array = array_map(function($line) {
return array_combine(['name', 'email'], str_getcsv($line));
}, explode("\n", $request('users')));
$json = json_encode($array);
var_dump($json);
The result would be:
string(133) "[{"name":"user 1","email":"user1#email.com"},{"name":"user 2","email":"user2#email.com"},{"name":"user 3","email":"user3#email.com"}]"
Try this
$xx = "user 1, user1#email.com\nuser 2, user2#email.com\nuser 3, user3#email.com";
$xxx = explode("\n",$xx);
$res = [];
foreach($xxx as $y)
{
$new = explode(',',$y);
$res[] = [
'name' => $new[0],
'email' => $new[1]
];
}
echo json_encode($res,true);
Output will be
[
{
"name":"user 1","email":" user1#email.com"
},
{
"name":"user 2","email":" user2#email.com"
},
{
"name":"user 3","email":" user3#email.com"
}
]
Try this
$data = explode("\n", trim(request('users')));
$result = collect($data)->map(function ($row) {
$columns = explode(',', $row);
return [
'name' => $columns[0] ?? null,
'email' => $columns[1] ?? null
];
});

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 can I get my foreach loop to output the result as one combined array instead of separate ones?

I'm receiving a JSON input, and I need to run it through a script and get the values returned in a new JSON array. However when I do so, it yields eg 3 separate arrays, not one big one as it received. Example:
Input:
[{
"auth": "aa03e76d0a8bab11e08250000c29b481",
"topic": "edafdff398fb22847a2f98a15ca3186e/1",
"value": "1000"
},
{
"auth": "aa03e76d0a8bab11e08250000c29b481",
"topic": "edafdff398fb22847a2f98a15ca3186e/1",
"value": "2000"
},
{
"auth": "aa03e76d0a8bab11e08250000c29b481",
"topic": "edafdff398fb22847a2f98a15ca3186e/2",
"value": "3000"
}]
I run it through the following script:
function clean($string) {
$string = str_replace(' ', '-', $string); // Replaces all spaces with hyphens.
return preg_replace('/[^A-Za-z0-9\-]/', '', $string); // Removes special chars.
}
//Get inputs from request
$data = array();
$data = json_decode(file_get_contents('php://input'), true);
$reply_array = array();
//Start looping through data
foreach($data as $mid => $input) {
//Dig out the installation id and register
$identify = explode('/',trim($input['topic'],'/'));
$installation = preg_replace('/[^a-z0-9_]+/i','',array_shift($identify));
$RegisterID = array_shift($identify)+0;
// Extract the cleaning supplies needed to clean and validate the data
$sql_get_detergent="SELECT ProfileID, Description, Lvl4, Register, BitNo, DataFormat, Units, LowAct, HighAct, Multiplier, FaultCondition, FaultText FROM DeviceProfiles WHERE RegisterID = '".$RegisterID."' ORDER BY RegisterID ASC";
$result_get_detergent = mysqli_query($con,$sql_get_detergent);
while($row_clean = mysqli_fetch_array($result_get_detergent)) {
//Write out the reply
$semantic = strtolower($row_clean['Lvl4']);
$reply_array['topic'] = $installation."/".clean($semantic);
}
print_r(json_encode($reply_array));
}
Output is not what I need - as seen here it yields 3 separate arrays, not one big one.
Current output:
{"topic":"edafdff398fb22847a2f98a15ca3186e\/"}
{"topic":"edafdff398fb22847a2f98a15ca3186e\/"}
{"topic":"edafdff398fb22847a2f98a15ca3186e\/"}
Desired output:
[{
"topic":"edafdff398fb22847a2f98a15ca3186e\/"
},
{
"topic":"edafdff398fb22847a2f98a15ca3186e\/"
},
{
"topic":"edafdff398fb22847a2f98a15ca3186e\/"
}]
What am I doing wrong? Appreciate your help!
You are printing each result in the foreach loop, and in the next iteration of the loop you overwrite the previous result.
Of course you get three single results that way.
Change your code like this:
$all_replies = array();
foreach($data as $mid => $input) {
// [...]
while($row_clean = mysqli_fetch_array($result_get_detergent)) {
$reply_array = array();
// Do you logic here - you can fill $reply_array as you want.
$all_replies[] = $reply_array;
}
}
print_r(json_encode($all_replies));
You could also use this approach, which is a smaller change:
$reply_array = array();
foreach($data as $mid => $input) {
// [...]
while($row_clean = mysqli_fetch_array($result_get_detergent)) {
// [...]
$reply_array[]['topic'] = $installation . "/" . clean($semantic);
}
}
print_r(json_encode($reply_array));
That will work for your example case, but you'll not be able to set another value apart from topic in a new assignment. You'd have to do it this way:
$reply_array = array();
foreach($data as $mid => $input) {
// [...]
while($row_clean = mysqli_fetch_array($result_get_detergent)) {
// [...]
$reply_array[] = array(
'topic' => $installation . "/" . clean($semantic),
'auth' => $your_auth_value,
);
}
}
print_r(json_encode($reply_array));
I prefer the first solution with an extra variable, but the other one works, too.
There is a small mistake in your code.
Replace below code :
$reply_array['topic'] = $installation."/".clean($semantic);
with :
$reply_array[]['topic'] = $installation."/".clean($semantic);

PHP json string: getting an associative array object

I have a json file with data like this (this is a partial view of the file to show structure):
{
"state": {
"ALABAMA": {
"ZOLD": [ "101", "102" ],
"ZNEW": [ "11", "12" ]
},
"ALASKA": {
"ZOLD": [ "5001", "5002", "5003", "5004", "5005", "5006", "5007", "5008", "5009", "5010"],
"ZNEW": [ "21", "22", "23", "24", "25", "26", "27", "28", "29", "20"]
}
}
}
What I want to do is search through it to find a value in the ZOLD field = $OLD, then return the value of the corresponding ZNEW array. I've tried going in with foreach and can get the arrays to echo out, but I'm not sure of what the value will be. Here's the code I have:
function translateZone($OLD)
{
$OLD = "5010"; //for testing purposes a constant but will be variable
$zStr = file_get_contents('getnew.json');
$zJson = json_decode($zStr,true);
foreach($zJson as $key=> $jsons)
{
foreach($jsons as $key=>$values)
{
foreach($values as $key=>$vals)
{
$counter=0;
foreach($vals as $key=>$vls)
{
$counter ++;
echo var_dump($vls);//I can see the values,but now what?
if ($vls == $OLD)
{
$zTemp = Help here -some array value of counter??
}
}
}
return $zTemp;
}
}
I've searched through a bunch of other questions but haven't found something close enough to help with the problem.
Additional information: I may or may not know the "state" string (i.e. "Alaska") but I may want to return this information as well based on the found value.
Thanks for the help.
Instead of trying to loop through ZOLD, you could use array_search (assuming that the $OLD value can only appear once in the data). This function will either return a number for the index of the value you search for or false if it cannot find it:
$index = array_search($OLD,$values['ZOLD']);
if ($index !== FALSE) {
$zTemp = $values['ZNEW'][$index];
}
This would replace your two innermost for loop (as you need the other loops to get down to this level) and iterate through each state. At this point as well, $key would be defined to your state name.
Here is another way to complete your task, this one with array_map function:
$jsonArray = json_decode($your_file_content, true);
$oldVal = "5005";
$result = [];
foreach( $jsonArray["state"] as $k => $v ) {
/**
* Here we're building an array or pairs ZOLD => ZNEW values
*/
$pairs = array_map(function($o, $n) {
return [ $o => $n ];
}, $v["ZOLD"], $v["ZNEW"]);
/**
* Filling up the result
*/
foreach( $pairs as $p )
if( isset($p[$oldVal]) )
$result[] = [
"state" => $k,
"ZNEW" => $p[$oldVal]
];
}
var_dump($result);
$result dump will contains a list or assoc arrays with "state" and "ZNEW" keys, if the corresponding ZNEW values will be found

Categories