Php mysql - get the values of last days and total of entries - php

I have to get the total values of last days into an array.
First, i have an array to get the last days:
$today = date('Y-m-d');
$ldays = [];
$db = 6;
for($i=-$db; $i<=0; $i++) {
array_push($ldays, date('Y-m-d', strtotime("$i days")));
}
//this will produce an array like this:
array (size=7)
0 => string '2018-12-21' (length=10)
1 => string '2018-12-22' (length=10)
2 => string '2018-12-23' (length=10)
3 => string '2018-12-24' (length=10)
4 => string '2018-12-25' (length=10)
5 => string '2018-12-26' (length=10)
6 => string '2018-12-27' (length=10)
And now, i pull the total of values of each days from the database.
SELECT COUNT(id) as total, data FROM users WHERE data >= '2018-12-21' GROUP BY data ORDER BY data ASC
The output will be an array like this:
array (size=2)
0 =>
array (size=2)
'total' => int 1
'data' => string '2018-12-21' (length=10)
1 =>
array (size=2)
'total' => int 1
'data' => string '2018-12-24' (length=10)
As you can see, the array is missing some days, so i need to cross the 2 arrays and see if a day exists in the 2 arrays:
$response = [];
for($i=0; $i<count($ldays); $i++) {
if(in_array($ldays[$i], array_column($rows_d, 'data'))) {
$response[$ldays[$i]] = 'yes';
}
else {
$response[$ldays[$i]] = 'no';
}
}
//this will make an array like so:
array (size=7)
'2018-12-21' => string 'yes' (length=3)
'2018-12-22' => string 'no' (length=2)
'2018-12-23' => string 'no' (length=2)
'2018-12-24' => string 'yes' (length=3)
'2018-12-25' => string 'no' (length=2)
'2018-12-26' => string 'no' (length=2)
'2018-12-27' => string 'no' (length=2)
But, insted of 'yes' and 'no', i want the array to be something like
array(size=7)
'2018-12-21' => int 1
'2018-12-22' => int 0
'2018-12-23' => int 0
'2018-12-24' => int 1
'2018-12-25' => int 0
'2018-12-26' => int 0
'2018-12-27' => int 0
and i keep getting an error if i do this :
if(in_array($ldays[$i], array_column($rows_d, 'data'))) {
$response[$ldays[$i]] = $rows[$i]['total'];
}
else {
$response[$ldays[$i]] = 0;
}
I guess this is because the rows array has only 2 entrys and the days array has 7. So, how can i obtain this? tks.

Rather than using in_array, use array_search combined with array_column to find the appropriate index into the $rows array instead:
if (($k = array_search($ldays[$i], array_column($rows_d, 'data'))) !== false) {
$response[$ldays[$i]] = $rows_d[$k]['total'];
}
else {
$response[$ldays[$i]] = 0;
}
Note that you have used both $rows and $rows_d in your code, I'm assuming it is supposed to be $rows_d in both cases.

It can looks prettier
$today = date('Y-m-d');
$ldays = [];
$db = 6;
for($i=-$db; $i<=0; $i++) {
$ldays[date('Y-m-d', strtotime("$i days"))] = 0;
}
$dbResult = [['total' => 1,'data' => '2018-12-21'],['total' => 2,'data' => '2018-12-24']]
foreach ($dbResult as $v) {
$ldays[$v['data']] = $v['total'];
}
var_dump($ldays);

Related

php array count values in 4 deep array

Im trying to count how many times a delivery date is in my array but i seem to only be able to count the first level.
array (size=48)
'2000-01-01' =>
array (size=2)
'date' => string '2000-01-01' (length=10)
0 =>
array (size=2)
'van' => string '0' (length=1)
0 =>
array (size=619)
'drop' => string '0' (length=1)
0 =>
array (size=29)
'id' => string '18137' (length=5)
'order_number' => string '13550' (length=5)
'reference' => string '' (length=0)
'delivery_date' => string '2000-01-01' (length=10)
I've tried:
$counts = array_count_values(array_flip(array_column($output, 'delivery_date')));
and
$array = array_map(function($element){
return $element['delivery_date'];
}, $output);
$array2 = (array_count_values($array));
print_r($array2);
in the end i either end up with a array to string error or the value 1.
how Would i go about counting these?
Thanks.
You could make use of array_walk_recursive and increment an array value every time the delivery_date key is present in the array at any level:
$counts = [];
array_walk_recursive(
$output,
static function ($value, string $key) use (&$counts): void {
if ($key === 'delivery_date') {
$counts[$value] = ($counts[$value] ?? 0) + 1;
}
}
);

Store unique values within foreach loop

Im trying to get value of ids for different values of a foreach loop but im confused how to go about it.
$revenue = array('pseudo1', 'pseudo2');
foreach ($revenue as $value) {
if (!$revenue_type) {
$st = getValueDescription($value);
foreach ($st as $stype) {
$tpe[] = $stype->id;
}
$rev[$value] = $tpe;
}
}
when i dump $rev this is what i get
array (size=1)
0 =>
array (size=3)
'pseudo1' =>
array (size=2)
0 => string '9' (length=1)
1 => string '19' (length=2)
'pseudo2' =>
array (size=4)
0 => string '9' (length=1)
1 => string '19' (length=2)
2 => string '1' (length=1)
3 => string '35' (length=2)
what i actually expect
array (size=1)
0 =>
array (size=3)
'pseudo1' =>
array (size=2)
0 => string '9' (length=1)
1 => string '19' (length=2)
'pseudo2' =>
array (size=4)
2 => string '1' (length=1)
3 => string '35' (length=2)
I need the result of my $rev to contain $value as keys but previous values of $tpe keeps adding up with each iteration, im confused how to achieve this.
Does this solve your problem?
$revenue = array('pseudo1', 'pseudo2');
$uniqueValues = [];
foreach ($revenue as $value) {
if (!$revenue_type) {
$st = getValueDescription($value);
$tpe = [];
foreach ($st as $stype) {
if (!in_array($stype->id, $uniqueValues)) {
$tpe[] = $stype->id;
$uniqueValues[] = $stype->id;
}
}
$rev[$value] = $tpe;
}
}
$uniqueValues holds the IDS you already added to the $rev variable, and the $tpe gets empty after every iteration

Updating table data from submission array cause all row to because the same data

I am pulling data from the database and displaying in a form.
I want the values to be edited and then the form when resubmitted will update the data in the table based on the corresponding row, however its updating the table based on the index value 4 only. All other data for the teamid is being replaced with the data in the arrays for the 4 index.
Here is the var_dump when the form is submitted ( this shows the modified data so its submitted correctly so assume its an issue with the loop )
array (size=12)
'teamid' => string '1' (length=1)
'activity' => string 'Mill 1' (length=6)
'activity2' => string 'Enter Details' (length=13)
'info' => string 'Auto process' (length=12)
'info2' => string 'Enter Details' (length=13)
'wsno' => string '1' (length=1)
'labour' =>
array (size=5)
0 => string 'Admin' (length=5)
1 => string 'QC Manager' (length=10)
2 => string 'Supervisor' (length=10)
3 => string 'Team Leaders' (length=12)
4 => string 'Line Operators' (length=14)
'hours' =>
array (size=5)
0 => string '1' (length=1)
1 => string '1' (length=1)
2 => string '2' (length=1)
3 => string '8' (length=1)
4 => string '8' (length=1)
'noworkers' =>
array (size=5)
0 => string '2' (length=1) << CHANGED THIS FROM 1 TO 2
1 => string '1' (length=1)
2 => string '1' (length=1)
3 => string '1' (length=1)
4 => string '3' (length=1)
'rateperhour' =>
array (size=5)
0 => string '11.00' (length=5)
1 => string '10.00' (length=5)
2 => string '9.00' (length=4)
3 => string '8.50' (length=4)
4 => string '8.00' (length=4)
'totalcost' =>
array (size=5)
0 => string '22' (length=2) << THIS IS THE NEW CALCULATED VALUE
1 => string '10.00' (length=5)
2 => string '18.00' (length=5)
3 => string '68.00' (length=5)
4 => string '192.00' (length=6)
'addteam' => string '' (length=0)
The value I changes was on the first index (0) -as No Workers to 2 and the value is correct when submitted
if(!isset($_GET['team'])) {
$teamid = 1;
} else {
$teamid = $_GET['team'];
}
$teamlq = mysqli_query($dbc,"SELECT * FROM `teams` WHERE `teamid` = '$teamid'");
$teamlr = mysqli_fetch_assoc($teamlq);
$actq = mysqli_query($dbc,"SELECT * FROM `teams` GROUP BY `activity` ASC");
$act = mysqli_fetch_assoc($actq);
$infoq = mysqli_query($dbc,"SELECT * FROM `teams` GROUP BY `info` ASC");
$info = mysqli_fetch_assoc($infoq);
$wsq = mysqli_query($dbc,"SELECT * FROM `workstation_costing` GROUP BY `wsno` ASC");
$ws = mysqli_fetch_assoc($wsq);
if(isset($_POST['addteam'])) {
$labour[] = $_POST['labour'];
$hours[] = $_POST['hours'];
$noworkers[] = $_POST['noworkers'];
$rateperhour[] = $_POST['rateperhour'];
$totalcost[] = $_POST['totalcost'];
$maxrows = 5;
$i = 0;
$info = $_POST['info'];
if($_POST['info'] == 'other') {
$info = $_POST['info2'];
}
$activity = $_POST['activity'];
if($_POST['activity'] == 'other'){
$activity = $_POST['activity2'];
}
echo "<pre>";
var_dump($_POST);
echo "</pre>";
do {
$labour = $_POST['labour'][$i];
$rateperhour = $_POST['rateperhour'][$i];
$hours = $_POST['hours'][$i];
$noworkers = $_POST['noworkers'][$i];
$totalcost = $_POST['totalcost'][$i];
$insert = mysqli_query($dbc,"UPDATE `teams` SET `activity` = '$activity',`info` = '$info',`wsno` = '$_POST[wsno]',`labour` = '$labour',`rateperhour`='$rateperhour',`hrsengaged` = '$hours',`noworkers`='$noworkers',`totalcost`='$totalcost' WHERE `teamid` = '$_POST[teamid]'");
echo mysqli_error($dbc);
$i++;
}while ($i < $maxrows);
}
Here is a screenshot of the table showing teamid 1 which the form is updating
( before form submission )
Notice that inside the loop you do:
$insert = mysqli_query($dbc,"UPDATE `teams` SET `activity` = '$activity',`info` = '$info',`wsno` = '$_POST[wsno]',`labour` = '$labour',`rateperhour`='$rateperhour',`hrsengaged` = '$hours',`noworkers`='$noworkers',`totalcost`='$totalcost' WHERE `teamid` = '$_POST[teamid]'");
but you never update the $_POST[teamid] so in each iteration you update all the fields with that $_POST[teamid] with the current data of the loop -> this cause to the table has only the last loop values for all the row with that teamid.
In order to overcome that you can add ID column to your table and in the loop update the row by its ID rather then the teamid -> this will result in updating 1 row at each iteration

Add entries together based on key in array PHP

As you can see I have a key called dateTime which holds dates. What I need to do is add all the entries together for each date and return the array. So I simply got one dateTime per date with all the entries of that day added together. I do not know the dateTime inputs ahead of time as I have a crawler that constantly inserts data into my database.
How would you go about doing that in the most efficient way? I imagine I would have to do a foreach loop and somehow check if the key value (dateTime) changes from the previous key value. And then create a brand new array that I return
An example of the array is as follows:
array (size=130)
0 =>
array (size=2)
'dateTime' => string '2015-09-01' (length=10)
'entries' => string '225' (length=3)
1 =>
array (size=2)
'dateTime' => string '2015-09-01' (length=10)
'entries' => string '218' (length=3)
2 =>
array (size=2)
'dateTime' => string '2015-09-01' (length=10)
'entries' => string '217' (length=3)
3 =>
array (size=2)
'dateTime' => string '2015-09-01' (length=10)
'entries' => string '225' (length=3)
4 =>
array (size=2)
'dateTime' => string '2015-09-02' (length=10)
'entries' => string '231' (length=3)
5 =>
array (size=2)
'dateTime' => string '2015-09-02' (length=10)
'entries' => string '220' (length=3)
6 =>
array (size=2)
'dateTime' => string '2015-09-03' (length=10)
'entries' => string '223' (length=3)
7 =>
array (size=2)
'dateTime' => string '2015-09-03' (length=10)
'entries' => string '237' (length=3)
8 =>
array (size=2)
'dateTime' => string '2015-09-03' (length=10)
'entries' => string '220' (length=3)
So it returns an array like this
array (size=130)
0 =>
array (size=2)
'dateTime' => string '2015-09-01' (length=10)
'entries' => string '660' (length=3)
1 =>
array (size=2)
'dateTime' => string '2015-09-02' (length=10)
'entries' => string '451' (length=3)
2 =>
array (size=2)
'dateTime' => string '2015-09-03' (length=10)
'entries' => string '680' (length=3)
Edit With the help of you guys, I ended up doing the following to get the right format.
function prepareArrayForGraphDates($array){
$results = [];
$finalResult = [];
foreach ($array as $value) {
if (!isset($results[$value['dateTime']])) {
$results[$value['dateTime']] = 0;
}
$results[$value['dateTime']] += $value['entries'];
}
$keyNames = array_keys($results);
for ($x = 0; $x < sizeof($results); $x++) {
$finalResult[$x]['dateTime'] = $keyNames[$x];
$finalResult[$x]['entries'] = $results[$keyNames[$x]];
}
return $finalResult;
}
Use the fact that array keys are unique...
$results = [];
foreach ($array as $value) {
if (!isset($results[$value['dateTime']])) {
$results[$value['dateTime']] = 0;
}
$results[$value['dateTime']] += $value['entries'];
}
You can use an array like a set or a dictionary, using the date as the key.
$data = [
[
'datetime'=>'2015-09-02',
'entries' => 220
]
// ... other entries snipped ...
];
$results = [];
foreach ($data as $date => $entry)
{
// if the date has already been recorded with an initial value, add to it
if (array_key_exists($date, $results) {
$results[$date] += $entry
} else {
// the date is new; add it to the results and set its initial value
$results[$date] = $entry;
}
}

Find arrays that share a common value from collection of arrays. May be 0 or more matches

I have the following data structure:
array (size=3)
0 =>
array (size=4)
0 => string 'apple' (length=5)
1 => string 'colophon' (length=8)
2 => string 'byo-fusion-drive' (length=16)
3 => string 'scroll-targeting' (length=16)
1 =>
array (size=3)
0 => string 'apply' (length=5)
1 => string 'exploring-web-typography' (length=24)
2 => string 'on-performance-content-management' (length=33)
2 =>
array (size=3)
0 => string 'macbook' (length=7)
1 => string 'colophon' (length=8)
2 => string 'nifty-minidrive' (length=15)
I'm trying to find out which, if any, arrays in my collection of arrays share a common value.
E.g: Arrays 0 and 2 share the string "colophon".
I've tried using array_intersect but this, of course, returns NULL since array 1 has no values in common with the others.
Also, it's possible (likely even) that in any given collection there will be no common value. The collection of arrays will always contain at least two arrays. There could be any number of additional arrays in the collection.
With the data described above, the end result should be something like this:
array (size=2)
0 =>
array (size=4)
0 => string 'apple' (length=5)
1 => string 'colophon' (length=8)
2 => string 'byo-fusion-drive' (length=16)
3 => string 'scroll-targeting' (length=16)
1 =>
array (size=3)
0 => string 'macbook' (length=7)
1 => string 'colophon' (length=8)
2 => string 'nifty-minidrive' (length=15)
I.e: With array 1 (from the original) being removed as it shares no common value.
I'm sure there's a simple way to do this, but I have been trying for 8+ hours now and have decided to ask for help.
Anyone?
You'll need to iterate it with a nested loop. like so:
$array = array(
array(
"apple",
"colophon",
"byo-fusion-drive",
"scroll-targeting"
),
array(
"apply",
"exploring-web-typography",
"on-performance-content-management"
),
array(
"macbook",
"colophon",
"nifty-minidrive"
)
);
for ($i = 0; $i < count($array); $i++) {
for ($j = $i+1; $j < count($array); $j++) {
var_dump(array_intersect($array[$i], $array[$j]));
}
}
Which outputs:
array (size=0)
empty
array (size=1)
1 => string 'colophon' (length=8)
array (size=0)
empty
A simple modification to the loop gives the expected behavior:
$result = array();
for ($i = 0; $i < count($array); $i++) { //Start from the first array, and continue up to all of them.
for ($j = $i+1; $j < count($array); $j++) { //Start with the current array of $i, +1. So that collisions never occur.
if (count(array_intersect($array[$i], $array[$j])) !== 0) { //If there are common values (the array_intersect() function returns a non-empty array
if (!in_array($array[$i], $result)) $result[] = $array[$i]; //Add the first array (if it's not there already)
if (!in_array($array[$j], $result)) $result[] = $array[$j]; //Add the second array (if it's not there already)
}
}
}
Which outputs
array (size=2)
0 =>
array (size=4)
0 => string 'apple' (length=5)
1 => string 'colophon' (length=8)
2 => string 'byo-fusion-drive' (length=16)
3 => string 'scroll-targeting' (length=16)
1 =>
array (size=3)
0 => string 'macbook' (length=7)
1 => string 'colophon' (length=8)
2 => string 'nifty-minidrive' (length=15)
Try
$arr = array (
array('apple', 'colophon', 'byo-fusion-drive', 'scroll-targeting', ),
array('apply', 'exploring-web-typography', 'on-performance-content-management', ),
array('macbook', 'colophon', 'nifty-minidrive', 'nifty-minidrive', ),
);
$repeated_values = array_keys(
array_filter(
array_count_values(
array_reduce($arr, function ($res, $value) {
return array_merge($res, array_unique($value));
}, array()
)
), function ($count) {
return $count > 1;
})
);
$result = array_filter($arr, function($value) use ($repeated_values) {
if (sizeof(array_intersect($repeated_values, $value)) > 0) return true;
});
var_dump($result);
Output
array (size=2)
0 =>
array (size=4)
0 => string 'apple' (length=5)
1 => string 'colophon' (length=8)
2 => string 'byo-fusion-drive' (length=16)
3 => string 'scroll-targeting' (length=16)
2 =>
array (size=4)
0 => string 'macbook' (length=7)
1 => string 'colophon' (length=8)
2 => string 'nifty-minidrive' (length=15)
3 => string 'nifty-minidrive' (length=15)

Categories