I have multiple JSON files on my server that I need to parse and then insert the parsed data into my database. For each file, I need to parse the nested “datasets” sets array, which also contains multiple nested arrays, and then insert the data from the multiple nested arrays into my database.
Each file contains differing and ever-changing nested datasets, so I am attempting to write a script that will dynamically build a sql insert statement using data from the arrays.
EXAMPLE JSON DATA
{
"title" : "Exported Data",
"timestamp":"3/17/2017 10:35:13 PM", // I need the date from this string timestamp
"description":"this is unused",
"datasets":[
{
"ab":[{ // I need this key value “ab” for the table name
"STID":"1", // I need both the “STID” for the column name, and the value for the record row
"qty":"440",
"bal":"532882.71",
"rem":"11.52"
},
{
"STID":"2",
"qty":"393",
"bal":"406825.45",
"rem":"11.16"
},
{
"STID":"3",
"qty":"517",
"bal":"556259.82",
"rem":"11.13"
}]
},
{
"act":[{
"STID":"1",
"BEG":"586",
"DEL":"2",
"RET":"3",
"EBO":"1",
"PO":"0",
"CO":"0",
"TX":"2",
"RX":"3",
"CUR":"584",
"PTD":"-2",
"WTD":"-19",
"MTD":"-6"
},
{
"STID":"2",
"BEG":"519",
"DEL":"12",
"RET":"2",
"EBO":"1",
"PO":"0",
"CO":"0",
"TX":"0",
"RX":"0",
"CUR":"528",
"PTD":"9",
"WTD":"-3",
"MTD":"65"
},
{
"STID":"3",
"BEG":"682",
"DEL":"6",
"RET":"4",
"EBO":"2",
"PO":"0",
"CO":"0",
"TX":"0",
"RX":"0",
"CUR":"682",
"PTD":"0",
"WTD":"2",
"MTD":"22"
}]
},
{
"cashproj":[{
"STID":"1",
"DlyProj":"2542.4025",
"RentCol":"1090.33",
"PerCol":"42.8858"
},
{
"STID":"2",
"DlyProj":"1893.44",
"RentCol":"2214.48",
"PerCol":"116.9553"
},
{
"STID":"3",
"DlyProj":"2614.24",
"RentCol":"1508.06",
"PerCol":"57.6863"
}]
}
]}
-
The MySQL tables are named the same as the dataset’s nested array key (i.e. “ab”, “act”, “cashproj”, etc…).
For each dataset, I am wanting to loop through each nested array to then create and run a sql query using data from both the top-level array key values, the dataset key name, and then the dataset array keys and values, for example:
This is what I currently have:
$the_array = json_decode($json, true);
$topdata = new RecursiveArrayIterator($the_array);
$start = 'INSERT INTO ';
foreach ($topdata as $key => $value)
{
if($key == 'timestamp')
{
$timestamp = strtotime($value);
}
if($key == 'datasets')
{
foreach ($value as $k => $v)
{
foreach ($v as $k2 => $v2)
{
foreach ($v2 as $dataset => $dsvalue)
{
$col = '';
$val = '';
foreach ($dsvalue as $dskey => $dsval)
{
$col .= $dskey . ', ';
$val .= $dsval . ', ';
// echo "$dskey => $dsval <br>";
}
$col = rtrim($col,", ");
$val = rtrim($val,", ");
$sql = $start . $k2 . ' (date, ' . $col . ') VALUES (' . $timestamp . ', ' . $val . ')';
// echo $sql . '<br><br>';
// $q = new Query();
// $q->insertDB($sql);
}
}
}
}
}
I'm hoping someone can show me a better or more-efficient method of writing this, that doesn't include five nested foreach statements.
Additionally, I'm not sure I am handling the conversion of the timestamp correctly. I will later use this column in conjunction with DateDiff/DateAdd to find data between periods. If current method is not right, what is?
Thanks in advance for your time and response.
Related
I have a function for arrays that I insert in db.
$data = array(
"This\tIs\tAn\tExample\tOne\tOf\tMy\tArrays\"
);
I formatted it correctly and given output is with:
$result = array_walk($data, function(&$item) { $item = '{ ' .str_replace("\t", ', ', $item) . ' }'; });
and the result of one of the rows that is inserted in db in JSON format is:
{ This, is, Example }, { One, Of, My, Arrays}
and all of them are formatted that way.
How can I bypass this to get desired format like:
{ This, is, Example, One, Of, My, Arrays}
If you want to convert this
$data = array(
"This\tIs\tAn\tExample\tOne\tOf\tMy\tArrays\"
);
to this
{ This, is, Example, One, Of, My, Arrays}
you can simply do it by
$result = [];
foreach ($data as $index => $value) {
$result[] = implode(',', explode("\t", $value));
}
$result = '{' . implode(',', $result) . '}';
How to insert multiple arrays with a foreach in rows of databases?
It's not a problem with an array, but my problem is to use two arrays or more.
my php code:
$checkBox1 = implode(',', $_POST['goinput1']);
$checkBox2 = implode(',', $_POST['goinput3']);
$mark3=explode(',', $checkBox1);
$mark4=explode(',', $checkBox2);
foreach($mark3 as $out3)
{
$sql_sub = "INSERT INTO sub_forms
(bord_mizban,bord_mihman)
VALUES ('$out3','$out4')";
if ($conn->query($sql_sub) === TRUE) {
} else {
}
}
**
I want the out 4 variable insert to the database with the out 3 variable
**
Iterate over $mark3 using indexes ($key) and get element under same key:
foreach($mark3 as $key => $out3)
{
echo $out3 . '; ' . $mark4[$key];
}
The short answer is:
foreach($mark3 as $key => $out3) {
$values = "'$out3."','".$mark4[$key]."'"
$sql_sub = "INSERT INTO sub_forms
(bord_mizban,bord_mihman)
VALUES ($values)";
if ($conn->query($sql_sub) === TRUE) {
} else {
}
}
That would fix your actual question. However, there is a better way to do this, with only 1 sql query.
foreach($mark3 as $key => $out3) {
$valuesArray[] = "('$out3."','".$mark4[$key]."')" // this makes an array of your value sets.
}
$values = join(", ", $valuesArray) // this joins your array to one string, with each entry separated by a comma.
$sql_sub = "INSERT INTO sub_forms
(bord_mizban,bord_mihman)
VALUES $values";
if ($conn->query($sql_sub) === TRUE) {
} else {
}
This it´s my little script, but don´t get right results at the moment :
<?php
// Delimiters betweeb data "*" elements in each data delimiters ","
$data_string="house1,403,phone1*house2,404,phone2*house3,403,phone3*house4,405,phone3";
// Explode $data_string for "~" delimiter
$data_exp=explode("*",$data_string);
//
// Loop 1
foreach($data_exp as $data_1)
{
$data_exp_compar=explode(",",$data_1);
// We want see the elements with the same data in common in second position (403,404,etc)
$data_common_1[]=$data_exp_compar[1];
$data_common_2[]=$data_exp_compar[1];
}
$a=array_values(array_intersect_key($data_common_1,$data_common_2));
$b=array_count_values(array_intersect_key($data_common_1,$data_common_2));
foreach($a as $aa=>$values)
{
echo $aa;
print "<br>";
}
?>
The idea in this script. It scans the data inside "$data_string", as you can see, all data delimiters is "*" and inside each data we have elements with "," as delimiter
I want get this output results and in this format :
PRODUCT Id: 403 (2 Actually)
1- house1,403,phone1
2- house3,403,phone3
PRODUCT Id: 404 (1 Actually)
1 - house2,404,phone2
Product Id: 405 (1 Actually)
1 - house4,405,phone4
As you can see the only element for compare it´s in the second position and it´s product´s id
I try many things but i can´t get works, or get finally results as i want show
Thank´s in advanced for all , regards
You can group them first then another foreach loop for printing result
$data_string="house1,403,phone1*house2,404,phone2*house3,403,phone3*house4,405,phone3";
$data_exp = explode("*",$data_string);
$group = []; // Initialize group array
foreach($data_exp as $data_1)
{
$data_exp_compar=explode(",",$data_1);
$group[$data_exp_compar[1]][] = $data_exp_compar; // Group by the number key after exploding
}
// Loop to each group, then print desired format
foreach ($group as $key => $value) {
echo 'Product ID: ' . $key . ' (' . count($value) . ' Actually)<br>';
foreach ($value as $k => $v) {
echo ++$k . ' - ' . implode(',', $v) . '<br>';
}
echo '<br>';
}
I would suggest using array_map and array_filter functions. Let me know if you have questions about this.
<?php
// Prepare data and input
$id = 403;
$data = "house1,403,phone1*house2,404,phone2*house3,403,phone3*house4,405,phone3";
// Convert string data to array
$data = explode("*", $data);
$data = array_map(function ($row) {
return explode(",", $row);
}, $data);
// Search the array
$response = array_filter($data, function ($row) use ($id) {
return $row[1] == $id;
});
print_r($response);
I am trying to loop through a JSON Array returning a unique date and all the tasks associated with that date.
This is an example of my JSON array:
<!-- language: lang-json -->
[
{
"task":"Clean my teeth",
"date":"today"
},
{
"task":"Jumping Jacks",
"date":"tomorrow"
},
{
"task":"Call Mom",
"date":"today"
},
{
"task":"Wash The Dog",
"date":"2017/03/01"
},
{
"task":"Clean The House",
"date":"today"
}
]
I want to display something like this:
Today
Clean my teeth
Call Mom
Tomorrow
Jumping Jacks
2017/03/01
Clean The House
Here is my function: I can get all the unique days but I'm not sure how to display the tasks associated with that day.
public static function Iteration()
{
$file = file_get_contents("newfile.php");
$result = rtrim( $file, ",");
$array = json_decode('[' . $result . ']');
$unique_dates = array();
$unique_tasks = array();
foreach($array as $item) {
if ( in_array($item->date, $unique_dates) ) {
continue;
}
$unique_dates[] = $item->date;
$time = strtotime($item->date);
$newformat = date('Y-m-d',$time);
echo '<h2>' . $newformat . '</h2>';
echo $item->task;
}
}
You can traverse the JSON list, and keep the unique records and store tasks at the same traversal.
By using the isset(), you can determine whether the key is unique or not.
Try this:
<?php
$json = '[{"task": "Clean my teeth","date": "today"},{"task": "Jumping Jacks","date": "tomorrow"},{"task": "Call Mom","date": "today"},{"task": "Wash The Dog","date": "2017/03/01"},{"task": "Clean The House","date": "today"}]';
$array = json_decode($json);
$res = array();
foreach ($array as $each) {
if (isset($res[$each->date]))
array_push($res[$each->date], $each->task);
else
$res[$each->date] = array($each->task);
}
foreach ($res as $date => $tasks){
echo "<h3>{$date}</h3>";
foreach ($tasks as $task)
echo "<p>$task</p>";
}
I try to request an array of IDs, to return each row with that ID, and push each into an Array $finalArray
But only the first result from the Query will output, and at the second foreach, it skips the while loop.
I have this working in another script, so I don't understand where it's going wrong.
The $arrayItems is an array containing: "home, info"
$finalArray = array();
foreach ($arrayItems as $UID_get)
{
$Query = "SELECT *
FROM items
WHERE (uid = '" . cleanQuery($UID_get) . "' )
ORDER BY uid";
if($Result = $mysqli->query($Query))
{
print_r($UID_get);
echo "<BR><-><BR>";
while ($Row = $Result->fetch_assoc())
{
array_push($finalArray , $Row);
print_r($finalArray );
echo "<BR><><BR>";
}
}
else
{
echo '{ "returned" : "FAIL" }'; //. mysqli_connect_errno() . ' ' . mysqli_connect_error() . "<BR>";
}
}
(the cleanQuery is to escape and stripslashes)
What I'm trying to get is an array of multiple rows (after i json_encoded it, like:
{ "finalArray" :
{ "home":
{ "id":"1",
"created":"0000-00-00 00:00:00",
"css": "{ \"background-color\" : \"red\" }"
}
},
{ "info":
{ "id":"2",
"created":"0000-00-00 00:00:00",
"css":"{ \"background-color\" : \"blue\" }"
}
}
}
But that's after I get both, or more results from the db.
the print_r($UID_get); does print info, but then nothing..
So, why am I not getting the second row from info? I am essentially re-querying foreach $arrayItem right?
Turns out... The leading space in the array, for the second item had to be trimmed with:
trim($UID_get);
Thanks GBD
after fetching array from mysql resource, try executing the following function, by passing fetched array as parameter.(inside your while loop)
function array_remove_indexes(&$arr)
{
$new_arr = array();
foreach($arr as $name => $val)
{
if(!is_int($name))$new_arr[$name]=$val;
}
$arr = $new_arr;
}