create file json with multi array from a external json file - php

I made a search in stackoverflow, really I found a lot of threads about multi arrays, but no one can help me, for that reason a new thread, maybe someone can help me find a solution for my problem.
What I want is create a Json file getting values from a external json file.
Example what I want:
{
"day":[[1522108800000,6305.5],[1522195200000,6440.7]],
"month":[[1522108800000,6305.5],[1522195200000,6440.7]]
}
I tried my code, but only can get values from 1 json file, and not from both json files.
Please see and let me know if you can help / suggest something.
// Array Min
$json_min = file_get_contents("https://min-api.cryptocompare.com/data/histominute?fsym=BTC&tsym=EUR&limit=5&e=kraken");
// Array Day
$json_day = file_get_contents("https://min-api.cryptocompare.com/data/histoday?fsym=BTC&tsym=EUR&limit=5&e=kraken");
$array_min = json_decode($json_min, true);
$array_day = json_decode($json_day, true);
$array = array (
'day' => array (),
'month' => array (),
);
foreach($array_min['Data'] as $key)
{
$close_min = $key['close'];
$time_min = $key['time'];
$time_min = $time_min *1000;
$close_day = $key2['close'];
$time_day = $key2['time'];
$time_day = $time_day *1000;
$array['day'][] = [$time_min, $close_min];
$array['month'][] = [$time_day, $close_day];
}
$json_data = json_encode($array);
file_put_contents( 'json/history.json', $json_data);

Your mistakes were primarily: $array['Data'] does not exist, so the foreach will never run, and also you did not have any $key2 defined to read from the second array. You need to loop over each input array separately.
The code below will do it quite neatly.
It's possible to do it more verbosely with two totally independent loops (one for each input), but: since you wish to perform the same operations on both inputs, it's possible to do it in less code by placing both input arrays into a wrapper array, and giving it the entries keys which match the keys in the output array:
// Array Min
$json_min = file_get_contents("https://min-api.cryptocompare.com/data/histominute?fsym=BTC&tsym=EUR&limit=5&e=kraken");
// Array Day
$json_day = file_get_contents("https://min-api.cryptocompare.com/data/histoday?fsym=BTC&tsym=EUR&limit=5&e=kraken");
//place both inputs into an array labelled "day" and "month", ready for processing
$input = array("day" => json_decode($json_min, true), "month" => json_decode($json_day, true));
$output = array (
"day" => array(),
"month" => array(),
);
//loop through each entry in the input array
foreach ($input as $key => $data)
{
//loop through the actual data and process it
foreach($data['Data'] as $datakey => $value)
{
$close = $value['close'];
$time = $value['time'] * 1000;
//output the data to an array in "output" with the same key as the input array we're currently processing
$output[$key][] = [$time, $close];
}
}
$json_data = json_encode($output);
file_put_contents( 'json/history.json', $json_data);
See here: https://eval.in/1027493 for a working demo.

Related

php var with multiple assoc arrays, get values one array at a time

Originally I was taking an uploaded .csv file and iterating through the values one row at a time.. with the below while loop.
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
var_dump($data);
$importIt = $repo->impThreeCSV($which, $data);
}
I have redone the .csv upload functionality to now be a web form where I send json to the PHP file on a 'save button'. I now have a variable with multiple associative arrays in it..
$fd = json_decode($df, true);
var_dump($fd);
For instance the dump above contains multiple arrays such as below: i.e. (~300 similar arrays as below).
array (size=806)
0 =>
array (size=18)
'ATM_ID' => string 'AFF-MIL-TWR' (length=11)
'FAC_IDENT' => string 'AFF' (length=3)
'LG_NAME' => string 'BLACH BLAH ACADEMY' (length=20)
'BASIC_TP' => string 'MIL-TWR' (length=7)
.................
How can I iterate through the VALUES only in these arrays, one at a
time in the same fashion as my original while loop.. (this would be
ideal so I don't have to redo the whole back-end).
I am having issues handling the multiple arrays and getting the
values only out..
I have tried the below two attempts, I just get 'arrayarrayarray' or
similar in var_dump. Do I need to break out each array into it's
own var? What am I doing wrong here? Do I need to run a count on how
many arrays consist in my var?
$fd = json_decode($df, true);
var_dump($fd);
$data = array_values($fd);
foreach ($data as $array_key) {
echo $array_key;
}
$array_keys = array_keys($fd);
foreach ($array_keys as $array_key) {
echo $array_key;
}
P.S. No, I can't use pandas, I wish.
Assuming you want to process the data in the same way as your original piece of code, you would just use something like:
foreach ($fd as $data) {
$importIt = $repo->impThreeCSV($which, array_values($data));
}
Note I've used array_values to convert $data from an associative array to a numerically indexed one, i.e. the same format as fgetcsv returns. This may - dependent on your $repo->impThreeCSV code - not be necessary.
You need to do a foreach to loop through each array, and then do another foreach to loop through every value of the array you're looping through.
$decodedJson = [
[
'ATM_ID' => 'AFF-MIL-TWR 1',
'FAC_IDENT' => 'AFF',
'LG_NAME' => 'BLACH BLAH ACADEMY',
'BASIC_TP' => 'MIL-TWR',
],
[
'ATM_ID' => 'AFF-MIL-TWR 2',
'FAC_IDENT' => 'AFF',
'LG_NAME' => 'BLACH BLAH ACADEMY',
'BASIC_TP' => 'MIL-TWR',
],
];
foreach ($decodedJson as $array) {
foreach ($array as $item) {
print $item; # => AFF-MIL-TWR 1
}
}

PHP - Merge append multiple json arrays

I need to merge/join multiple json string that contains arrays (which also need to be merged) but I don't know what is the best way to achieve this :
Initial array of json strings (called $rrDatas in my example below):
Array
(
[0] => {"asset":[1],"person":[1]}
[1] => {"asset":[2]}
)
Expected result :
{"asset":[1,2],"person":[1]}
The main difficulty is that the number of arrays is undefined (my example is made with 2 arrays but it could be 3,4 etc.). The second difficulty is that there can be multiple properties (like "asset", "person" etc. however always arrays). These possible properties are known but are many so it would be better if the algorithm is dynamic.
What I am able to do at the moment :
$mergedAssets['asset'] = [];
foreach ($rrDatas as $rrData)
{
$rrDataJson = \GuzzleHttp\json_decode($rrData, true);
$mergedAssets['asset'] = array_merge($mergedAssets['asset'],$rrDataJson['asset']);
}
$result = \GuzzleHttp\json_encode($mergedAssets, true);
Result :
{"asset":[1,2]}
This works well but this is not dynamic, should I duplicate this part for each possible properties (i.e. "person", etc.) ?
Thanks,
Guillaume
Edit : Brett Gregson's and krylov123's answers below helped me build my own solution which is a mix between both suggestion:
$mergedJson = [];
foreach ($rrDatas as $rrData)
{
$rrDataJson = \GuzzleHttp\json_decode($rrData, true);
foreach(array_keys($rrDataJson) as $property)
{
$mergedJson[$property] = array_merge($mergedJson[$property] ?? [], $rrDataJson[$property]);
}
}
return \GuzzleHttp\json_encode($mergedJson, true);
Find below a better example :
$rrDatas = Array (
[0] => {"asset":[1,2],"person":[1],"passive":[1]}
[1] => {"asset":[3],"charge":[1],"passive":[2]}
)
Which must result in :
{"asset":[1,2,3],"person":[1],"passive":[1,2],"charge":[1]}
Edit 2 : I have just tried Progrock's solution and it seems to work perfectly as well : https://3v4l.org/7hSqi
You can use something like:
$output = []; // Prepare empty output
foreach($rrDatas as $inner){
foreach($inner as $key => $value){
$output[$key][] = $value;
}
}
echo json_encode($output); // {"asset":[1,2],"person":[1]}
Which should give you the desired output. This should work regardless of the keys within the individual arrays and even with empty arrays.
Working example here
Another example with more arrays and more keys and empty arrays
<?php
$array =
[
'{"asset":[1],"person":[1]}',
'{"asset":[2]}',
];
$array = array_map(function($v) { return json_decode($v, true);}, $array);
$merged = array_merge_recursive(...$array);
print json_encode($merged);
Output:
{"asset":[1,2],"person":[1]}
You need to use foreach ($array as $key => $value) iteration, to be able to dynamicaly use keys of your json array (e.g. "asset" and "person").
Solution:
$mergedAssets['asset'] = [];
foreach ($rrDatas as $key => $value)
{
$rrDataJson = \GuzzleHttp\json_decode($value, true);
$mergedAssets[$key] = array_merge($mergedAssets[$key],$rrDataJson[$key]);
}
$result = \GuzzleHttp\json_encode($mergedAssets, true);

How to make key value by explode and arrange matching key values into one key?

I am recently facing a practical problem.I am working with ajax form submission and there has been some checkboxes.I need all checkboxes with same name as key value pair.Suppose there is 4 checkboxes having name attribute =checks so i want something like $arr['checks'] = array(value1, value2, ...)
So i am getting my ajax $_POST code as suppose like: name=alex&checks=code1&checks=code2&checks=code3
I am using below code to make into an array
public function smdv_process_option_data(){
$dataarray = array();
$newdataarray = array();
$new = array();
$notices = array();
$data = $_POST['options']; // data received by ajax
$dataarray = explode('&', $data);
foreach ($dataarray as $key => $value) {
$i = explode('=', $value);
$j = 1;
if(array_key_exists($i[0], $newdataarray)){
if( !is_array($newdataarray[$i[0]]) ){
array_push($new, $newdataarray[$i[0]]);
}else{
array_push($new, $i[1]);
}
$newdataarray[$i[0]] = $new;
}else{
$newdataarray[$i[0]] = $i[1];
}
}
die($newdataarray);
}
Here i want $newdataarray as like below
array(
'name' => 'alex',
'checks => array(code1, code2, code3),
)
But any how I am missing 2nd value from checks key array.
As I see it you only need to do two explode syntaxes.
The first on is to get the name and here I explode on & and then on name= in order to isolate the name in the string.
The checks is an explode of &checks= if you omit the first item with array_slice.
$str = 'name=alex&checks=code1&checks=code2&checks=code3';
$name = explode("name=", explode("&", $str)[0])[1];
// alex
$checks = array_slice(explode("&checks=", $str), 1);
// ["code1","code2","code3"]
https://3v4l.org/TefuG
So i am getting my ajax $_POST code as suppose like: name=alex&checks=code1&checks=code2&checks=code3
Use parse_str instead.
https://php.net/manual/en/function.parse-str.php
parse_str ( string $encoded_string [, array &$result ] ) : void
Parses encoded_string as if it were the query string passed via a URL and sets variables in the current scope (or in the array if result is provided).
$s = 'name=alex&checks=code1&checks=code2&checks=code3';
parse_str($s, $r);
print_r($r);
Output
Array
(
[name] => alex
[checks] => code3
)
You may think this is wrong because there is only one checks but technically the string is incorrect.
Sandbox
You shouldn't have to post process this data if it's sent correctly, as that is not included in the question, I can only make assumptions about it's origin.
If your manually creating it, I would suggest using serialize() on the form element for the data for AJAX. Post processing this is just a band-aid and adds unnecessary complexity.
If it's from a source outside your control, you'll have to parse it manually (as you attempted).
For example the correct way that string is encoded is this:
name=alex&checks[]=code1&checks[]=code2&checks[]=code3
Which when used with the above code produces the desired output.
Array
(
[name] => alex
[checks] => Array
(
[0] => code1
[1] => code2
[2] => code3
)
)
So is the problem here, or in the way it's constructed...
UPDATE
I felt obligated to give you the manual parsing option:
$str = 'name=alex&checks=code1&checks=code2&checks=code3';
$res = [];
foreach(explode('&',$str) as $value){
//PHP 7 array destructuring
[$key,$value] = explode('=', $value);
//PHP 5.x list()
//list($key,$value) = explode('=', $value);
if(isset($res[$key])){
if(!is_array($res[$key])){
//convert single values to array
$res[$key] = [$res[$key]];
}
$res[$key][] = $value;
}else{
$res[$key] = $value;
}
}
print_r($res);
Sandbox
The above code is not specific to your keys, which is a good thing. And should handle any string formatted this way. If you do have the proper array format mixed in with this format you can add a bit of additional code to handle that, but it can become quite a challenge to handle all the use cases of key[] For example these are all valid:
key[]=value&key[]=value //[key => [value,value]]
key[foo]=value&key[bar]=value //[key => [foo=>value,bar=>value]]
key[foo][]=value&key[bar][]=value&key[bar][]=value //[key => [foo=>[value]], [bar=>[value,value]]]
As you can see that can get out of hand real quick, so I hesitate to try to accommodate that if you don't need it.
Cheers!

PHP build json from a dynamic number of arrays

I have a dynamic number of pages in my web project. It depends on data from the database. I may have 1 page or 10 pages. I put the data selected on each page in session, and finally want to build an array. At the moment I am building JSON from 4 arrays. (In session all the keys are level + int in ascending order. If session x is missing I don't have any data on 6+ levels)
$level1 = array();
$level2 = array();
$level3 = array();
$level4 = array();
if (isset($_SESSION['level1'])) {
$level1 = $_SESSION['level1'];
}
//the same for 3 more levels in session
$array = array(
"first" => ($level1),
"second" => ($level2),
"third" => ($level3),
"fourth" => ($level4)
);
json_encode($array);
Example of output of the json_encode($array):
{"first":["1","2"],"second":["4","6","8","9"],"third":["13","14","17","18"],"fourth":["33","34","35","36"]}
I tried to check how would json_encode work with array_push(), but I get an array of JSON objects instead of a single json object.
$result = array();
array_push($result, ["key1" => $_SESSION["level1"]]);
array_push($result, ["key2" => $_SESSION["level2"]]);
array_push($result, ["key3" => $_SESSION["level3"]]);
echo json_encode($result);
and the output:
[{"key1":["1","2"]},{"key2":["4","5","6"]},{"key3":["13","14","15"]}]
I will make everything iteratively, but I want to know if it is possible to make a single JSON object instead of array of JSONs. Thanks!
You can just add the keys to the array without any need for a function.
$result = array();
$result["key1"] = $_SESSION["level1"];
$result["key2"] = $_SESSION["level2"];
$result["key3"] = $_SESSION["level3"];
echo json_encode($result);

Can't push all array items into a second array PHP

So I have an array ($items) which has about 900 items in it. What I'm trying to do is, for the items that are read ($key["status"] == 1) which is about 300 items -> push those into a second array ($lifeSpanArray) with two attributes (added_date and read_date).
For some reason, when I try to push items into the lifespan array, I only have one item. Like I said, there are around 300 items that are status read - and I can dump those out, so I believe I am making a mistake with building my lifeSpanArray and pushing into it.
Any help much appreciated!
$items = $pocket->retrieve($params, $accessToken);
$numberArticles = count($items["list"]);
$hasRead = 0;
$hasNotRead = 0;
$readDatesArray = array();
$lifeSpanArray = array();
foreach ($items['list'] as $key) {
if ($key["status"] == 1) {
$hasRead++;
$timeAdded = date('m/d/Y', $key["time_added"]);
$dateRead = date('m/d/Y', $key["time_read"]);
// Where the problem is - only one item added
$lifeSpanArray['timeAdded'] = $timeAdded;
$lifeSpanArray['timeRead'] = $dateRead;
//Push into the read dates array
array_push($readDatesArray, $dateRead);
}
else {
$hasNotRead++;
}
}
var_dump($lifeSpanArray);
As you are overwriting your $lifeSpanArray array on each iteration you're must be getting only last entry so what you need is a two-dimension array,
Change this,
//Push into lifespan array
$lifeSpanArray['timeAdded'] = $timeAdded;
$lifeSpanArray['timeRead'] = $dateRead;
to,
$lifeSpanArray[] = array('timeAdded' => $timeAdded,'timeRead' => $dateRead);
$lifeSpanArray['timeAdded'] = $timeAdded;
$lifeSpanArray['timeRead'] = $dateRead;
For the above code, you are actually assigning a scalar value to $lifeSpanArray['timeAdded'] and $lifeSpanArray['timeRead'].
To treat them as array and push values to them, you should first initialize timeAdded and timeRead as arrays first:
$lifeSpanArray = array(
'timeAdded' => array(),
'timeRead' => array()
);
And pushing values to them within the foreach loop:
$lifeSpanArray['timeAdded'][] = $timeAdded;
$lifeSpanArray['timeRead'][] = $dateRead;

Categories