I have a MySql table where I saved all workers names and the dates workers have to work on. I want to show a list containg all days of the current month and the worker names who have to work on the day that corresponds to them. Example:
February
1
2
3 - John Wick
5
6 - Martha Beck
etc.
This is the code I have in PHP but the loop is not working. I just get a list from 1 to 30 but it is not showing the data from database. If I run the loop without the (while ($n < 31)), I get all the records from database but I want to show the names just beside the day that correspond.
<?php
mysql_select_db($database_nineras, $nineras);
$query_res = sprintf("SELECT res_id, res_dateini, res_datefin, res_name FROM reservas ORDER BY res_dateini DESC");
$reservas = mysql_query($query_res, $nineras) or die(mysql_error());
$rreser = mysql_fetch_assoc($reservas);
$treser = mysql_num_rows($reservas);
$n = 1;
while ($n < 31) {
do {
++$n;
if ($n == date('d', strtotime($rreser['res_dateini']))) {
echo $n . ' - ' . $rreser['res_name'];
}
else {
echo $n;
}
} while ($rreser = mysql_fetch_assoc($reservas));
}
?>
The problem with your code is that the do-while loop is fetching all the rows returned by the query. So when you get to the second iteration of the while loop there's nothing left to fetch.
Rather than fetch the rows from the database each time through the loop, you can fetch them once and put them into an array whose index is the day numbers. Then you can loop through the days and print all the rows for each day.
Use date('j', ...) to get the date without a leading zero. Or change your SQL query to return DAY(res_dateini).
$results = array();
$reservas = mysql_query($query_res, $nineras) or die(mysql_error());
while ($rreser = mysql_fetch_assoc($reservas)) {
$d = date('j', strtotime($rreser['res_dateini'])));
$results[$d][] = $rreser['res_name'];
}
for ($day = 1; $day <= 31; $day++) {
echo "$day - " . (isset($results[$day]) ? implode(", ", $results[$day]) : "") . "<br>\n";
}
DEMO
Related
I'm working on a system report using PHP. I have a table with two columns (payment date and amount).
How I can use a while loop to calculate the total amount after each December through years? I tried to do it as per the screenshot attached but it displays the wrong sum after each December.
Below is how I did it:
<?php
$total=0;
$s = date('m');
$c = mysqli_query($con,"SELECT * FROM payroll_contribution_pssf WHERE employee_id='3' ORDER BY contribution_id ASC");
while($array = mysqli_fetch_array($c))
{
$m = date('m', strtotime($array['payroll_date']));
echo $array['payroll_date']." ".$array['employee_amount']."<br>";
if($m==12)
{
if($total == 0)
$total = $array['employee_amount'];
$total = $total + $array['employee_amount'];
echo number_format($total,0)."<br>";
}
}
?>
It seems you want it to calculate and display the total value of all the previous rows since the last total was calculated (or since the start of the dataset, in the case of the first iteration).
In that case the flaws in your logic are that you're
a) only adding to the total when it's the 12th month, and
b) you're not resetting it after you've reached the 12th month.
You need to have a "total" variable which is incremented each time you loop, and also you need to reset it to 0 after displaying it.
For example:
$total = 0;
$c = mysqli_query($con,"SELECT * FROM payroll_contribution_pssf WHERE employee_id='3' ORDER BY contribution_id ASC");
while ($array = mysqli_fetch_array($c))
{
$m = date('m', strtotime($array['payroll_date']));
echo $array['payroll_date']." ".$array['employee_amount']."<br>";
$total += $array['employee_amount']; //increment every time
if ($m == 12)
{
echo number_format($total, 0)."<br>";
$total = 0; //reset after displaying
}
}
I have this query now:
SELECT DATE_FORMAT(`dataNl`, \'%Y%m\') AS `Ym`, COUNT(*) AS `totale`
FROM `noleggio`
GROUP BY `Ym`
This help to get data for each month, but if a month with 0 value, this doesn't exist in the database, so I can't get it. I need a query that add remaining month setting the COUNT field to 0.
I made a PHP code to add months with 0 value into the array, but it only works if the year is only one, if I want to get more, this needs a lot of tricky code, I think there could be a solution with SQL.
This is the PHP code:
$t = array();
$m = array();
foreach ($months as $val) {
$t[] = $val['totale'];
$m[] = $val['Ym'];
}
for ($i = 0; $i < 12; ++$i) {
if (in_array($i + 201801, $m) == false) {
array_splice($t, $i, 0, 0);
}
}
Here is a PHP solution which requires min and max dates from the database:
// use the query SELECT MIN(dataNl), MAX(dataNl) FROM ... to
// find the first and last date in your data and use them below
$dates = new DatePeriod(
DateTime::createFromFormat('Y-m-d|', '2018-01-15')->modify('first day of this month'),
new DateInterval('P1M'),
DateTime::createFromFormat('Y-m-d|', '2018-12-15')->modify('first day of next month')
);
// assuming $rows contain the result of the GROUP BY query...
foreach ($dates as $date) {
$datestr = $date->format('Ym');
$index = array_search($datestr, array_column($rows, 'Ym'));
if ($index === false) {
echo $datestr . ' -> 0' . PHP_EOL;
} else {
echo $datestr . ' -> ' . $months[$index]['totale'] . PHP_EOL;
}
}
Try the below query:
SELECT DATE_FORMAT(`dataNl`, \'%Y%m\') AS `Ym`, COUNT(*) AS `totale`
FROM `noleggio`
GROUP BY MONTH(`dataNl`)
I am looking for some basic attendance logic. What I have done so far is that employees can click on two different kinds of buttons and mark themselves as Signed In, Signed Out (status 1 and 2) using one button and Break Start, Break Over (status 3 and 4) using the other button.
Now when I calculate employee's total Sign In hours and total Break hours for a particular date I do something like below.
First iterate over a loop of Starting date and Ending date for which I want to see the working hours.
Now first of all check if the employee logged in on a particular date, by finding a status 1 entry of that date.
If the employee logged in on that date, then I fetch all attendance records for that date.
Now I iterate over this date's attendance records add up the time differences starting from first status 1 (i.e. Login) to next status and from next status (which can be either a break start 3 or a log out 2) till the next status (which can be either break over 4 or log in 1).
This is working good and my working hours' calculations are coming fine.
There is however one logical part that I am not able to understand i.e. if the employee does not logout on the same date for which I have fetched out the records, then the time span from last login or break start till the logout are not getting calculated. Because the final logged out status does not fall on the same date for which I fetched the records.
So, I need some help in understanding any suggestions how this can be managed and how can I calculate the working hours if the employee's logout status falls on a different date than login date.
Thanks in advance.
Here is some code.
public function getEmployeeAttendance($company_uid , $emp_uid)
{
for($m=1; $m<=12; $m++)
{
$mon = strtotime(date('Y-' . $m . '-00'));
$first = date("Y-m-01", $mon); // First Date Of cuRRENT mONTH
$last = date("Y-m-t", $mon); // Last Date Of cuRRENT mONTH
$date[] = range_date($first, $last);
}
$atten = array();
//echo "<pre>";
foreach($date as $dt)
{
foreach($dt as $d)
{
// A function to check if there was a status 1 on this date
$myAttendance = $this->Attendance_Model->myAttendance($company_uid , $emp_uid, $d);
# If Employee Signed In on This Date (i.e. Status was 1)
if(count($myAttendance) >0)
{
# Calculate Working Hours
$attenRec = $this->Attendance_Model->getAttendanceRecords($company_uid , $emp_uid, $d);
$signInHrs = 0;
$breakHrs = 0;
$workingHrs = 0;
for($i=0; $i<count($attenRec); $i++)
{
// Get this record's status
$status = $attenRec[$i]['status'];
// Get next record's status
if(!empty($attenRec[$i + 1]))
{
if($status == '1' || $status == '4') // Sign In or Break Over
{
$thisTime = strtotime($attenRec[$i]['atten_time']);
$nextTime = strtotime($attenRec[$i + 1]['atten_time']);
$diff = round(($nextTime - $thisTime) / 3600, 2);
$signInHrs += $diff;
}
if($status == '3') // Break Start
{
$thisTime = strtotime($attenRec[$i]['atten_time']);
$nextTime = strtotime($attenRec[$i + 1]['atten_time']);
$diff = round(($nextTime - $thisTime) / 3600, 2);
$signInHrs += $diff;
$breakHrs += $diff;
}
}
}
$onlySignInHrs = floor($signInHrs);
$remainingSignInHrs = $signInHrs - $onlySignInHrs;
$signInMinutes = round($remainingSignInHrs * 60);
$myAttendance['signInHrs'] = $onlySignInHrs . " Hrs : " . $signInMinutes . " Min";
$onlyBreakHrs = floor($breakHrs);
$remainingBreakHrs = $breakHrs - $onlyBreakHrs;
$breakMinutes = round($remainingBreakHrs * 60);
$myAttendance['breakHrs'] = $onlyBreakHrs . " Hrs : " . $breakMinutes . " Min";
$workingHrs = $signInHrs - $breakHrs;
$onlyWorkingHrs = floor($workingHrs);
$remainingWorkingHrs = $workingHrs - $onlyWorkingHrs;
$workingMinutes = round($remainingWorkingHrs * 60);
$myAttendance['workingHrs'] = $onlyWorkingHrs . " Hrs : " . $workingMinutes . " Min";
}
# Save This Date's Attendance
$atten[] = $myAttendance;
}
}
return $atten;
}
I'm getting records from a MySQL database with this PHP function:
function someFunction($date){
// all distinct records
$query = "select count(distinct column_name) as alias from table_name where DATE(date_column) = '$date'";
$result = $connection->query($query);
$row = $result->fetch_assoc();
return $row['alias'];
// end of all distinct records
}
Now what the below PHP code does is, get the day in the date, compute the week of the month it belongs to and stores it an an array.
//while fetch_assoc returns records
//$result1 query: "select * from table_name where DATE(date) between '$first_date' and date_add('$end_date',interval 1 day)"
while ($row1 = $result1->fetch_assoc()) {
$date = $row1['date'];
$start = 1;
$end = 7;
for ($i = 1; $i <= 5; $i++) {
if ((int) date('d', strtotime($date)) >= $start && (int) date('d', strtotime($date)) <= $end) {
if (!isset($arr1[$i]) || !isset($arr2[$i])) {
$arr1[$i] = 0;
$arr2[$i] = 0;
}
++$arr1[$i];
$arr2[$i] = someFunction(date('Y-m-d', strtotime($date)));
}
$start += 7;
$end += 7;
}
}
Consider 1st, 2nd and 3rd belong to the same week, 1st has 3 records, 2nd has 4 and 3rd has 1. The while loop will iterate 7 times, each value returned by the someFunction() overwriting the value in $arr2[$i].
So my question is, how will I be able to check if the previous iteration date value is equal to the current date value?
So my question is, how will I be able to check if the previous iteration date value is equal to the current date value?
Pseudocode:
$lastValue = …; // initialization with a value that does not occur in the actual values,
// such as NULL, empty string, …
while(…) {
if($currentValue == $lastValue) {
// do something
}
else {
// do something else
}
// …
$lastValue = $currentValue; // set current value for next loop interation
}
I have a database table which stores which days (Monday to Sunday) are working days and which are not. The table includes 2 attributes, "day" (1, 2, 3, 4, 5, 6, 7 for Monday to Sunday) and "working". I use the numbers '0' and '1' to indicate if they are working days or not, '1' being non working day. I have set in the database for Friday, Saturday and Sunday to be nonworking (5, 6, 7).
$addrange = $annstart;
$minusday = 0; //numbers of nonworking days
$resultnonworking = mysql_query("SELECT dayid FROM workingdays WHERE working='1'");
while ($nonworking = mysql_fetch_array($resultnonworking))
{
while ($datediffdays > 1)
{
$addrange = date('Y-m-d', strtotime($addrange . ' + 1 day'));
$daycheck = date('N', strtotime($addrange));
if ($daycheck == $nonworking['dayid'])
{
$minusday = ++$minusday;
}
$datediffdays = --$datediffdays;
}
$startdaycheck = date('N', strtotime($annstart));
if ($nonworking['dayid'] == $startdaycheck)
$minusday = ++$minusday;
}
However my while loop only runs once and checks which of the dates are Fridays, leaving out Saturday, and Sunday.
Can somebody spot what is wrong with my code?
Thanks in advance.
Explanation to what you asked, your loop is as below.
while ($nonworking = mysql_fetch_array($resultnonworking))
{
while ($datediffdays > 1)
{
see it first fetches one record and then until the $datediffdays goes less then 1 it runs the inner loop.
now when you come back to the first loop the value of $datediffdays is already less than 1 so it doesn't goes into the second loop.
to make this workig you have to initialize $datediffdays inside first loop like,
while ($nonworking = mysql_fetch_array($resultnonworking))
{
$datediffdays = 5;
while ($datediffdays > 1)
{
where as the changes that you made now, fetces the record inside the while loop and then it reduces the value of $datediffdays variable only once a loop
and therefore it is working, because value of $datediffdays is not set to less than 1 the first time it comes inside the loop.
I can't suggest which will be the best approach as all of your code is not here
I've switched the inner while loop with the outer one, and with a little bit of changes, its working now. But I have no idea why it is working this way but not the other.
$addrange = date('Y-m-d', strtotime($annstart . ' - 1 day'));
$minusday = 0; //numbers of nonworking days
while ($datediffdays > 0)
{
$addrange = date('Y-m-d', strtotime($addrange . ' + 1 day'));
$checkrange = date('N', strtotime($addrange));
$resultnonworking = mysql_query("SELECT * FROM workingdays WHERE working='1'");
while ($nonworkingcheck = mysql_fetch_array($resultnonworking))
{
if($nonworkingcheck['dayid'] == $checkrange)
{
$minusday = $minusday + 1;
}
}
$range = $range." ".$addrange;
$datediffdays = $datediffdays-1;
}
$range = substr($range,11);