php mysql和嵌套循环

时间:2015-06-27 20:18:09

标签: php mysql loops calendar

我有一个包含以下条目的数据库:

Id | UserID | Date     | Time
1  | 1      | 06/29/15 | d
2  | 1      | 06/30/15 | n

我有以下php代码,根据数据库条目生成日历,它标记具有特定颜色的指定日期:

<?php
$cMonth = $_REQUEST["month"];
$cYear = $_REQUEST["year"];
$timestamp = mktime(0,0,0,$cMonth,1,$cYear);
$maxday = date("t",$timestamp);
$thismonth = getdate ($timestamp);
$startday = $thismonth['wday'];
$toddate = date("j");
$todmon = date("n");

for ($i=0; $i<($maxday+$startday); $i++)
{
    if (($i % 7) == 0)
        echo "<tr>";
    $getr = mysql_query("SELECT * FROM `reservations` WHERE `UserID` = 1");
    $datee = $i - $startday + 1;
    $nums = mysql_num_rows($getr);
    while ($row = mysql_fetch_assoc($getr))
    {
        $timestamp = strtotime($row['Date']);
        $bookeddate = date("d", $timestamp);
        $dates[$nums] = $bookeddate;
        $bookedmon = date("n", $timestamp);
        if ($cMonth == $bookedmon && $row['Time'] == 'd' && $bookeddate == $datee)
            echo "<td title='day booked' align='center' bgcolor='orange' valign='middle' height='20px'>". ($datee) . "</td>";
        else if ($cMonth == $bookedmon && $row['Time'] == 'n' && $bookeddate == $datee)
            echo "<td title='Night booked' align='center' bgcolor='black' color='white' valign='middle' height='20px'>". ($datee) . "</td>";
        else if ($cMonth == $bookedmon && $row['Time'] == 'c' && $bookeddate == $datee)
            echo "<td title='Completely booked' align='center' bgcolor='red' valign='middle' height='20px'>". ($datee) . "</td>";
    }
    if($i < $startday)
        echo "<td></td>";
    else if ($datee == $toddate && $cMonth == $todmon)
        echo "<td title='today' align='center' bgcolor='lime' valign='middle' height='20px'>". ($datee) . "</td>";
    else if ($datee != $bookeddate)
        echo "<td align='center' valign='middle' height='20px'>". ($datee) . "</td>";
    if(($i % 7) == 6)
        echo "</tr>";
}

问题是,它显示数据库中的第一个日期两次,另一个日期只显示一次。如何设置仅显示两个日期。

您可能需要在最终运行php代码。

1 个答案:

答案 0 :(得分:0)

问题是由使用$ bookeddate变量超出范围或弄乱大括号引起的。

这部分代码不在你的while($ row = mysql_fetch_assoc($ getr))循环中:

    if($i < $startday) echo "<td></td>";
    else if ($datee == $toddate && $cMonth == $todmon) echo "<td title='today' align='center' bgcolor='lime' valign='middle' height='20px'>". ($datee) . "</td>";
    else if ($datee != $bookeddate) echo "<td align='center' valign='middle' height='20px'>". ($datee) . "</td>";
    if(($i % 7) == 6 ) echo "</tr>";

但是你在这里使用$ bookeddate,这是在循环中定义的。这里它具有查询的最后一行的值并导致重复。

您可以采取哪些措施来避免与一个额外变量重复,但您应该完全重构代码。

for ($i=0; $i<($maxday+$startday); $i++) {
    $getr = mysql_query("SELECT * FROM `reservations` WHERE `UserID` = 1");
    $datee = $i - $startday + 1;
    $nums = mysql_num_rows($getr);
    $displayed = false;
    while ($row = mysql_fetch_assoc($getr)) {
        $timestamp = strtotime($row['Date']);
        $bookeddate = date("d", $timestamp);
        $dates[] = $bookeddate;
        $bookedmon = date("n", $timestamp);
        if ($cMonth == $bookedmon && $row['Time'] == 'd' && $bookeddate == $datee) {
            echo "<td title='day booked' align='center' bgcolor='orange' valign='middle' height='20px'>". ($datee) . "</td>";
            $displayed = true;
        } else if ($cMonth == $bookedmon && $row['Time'] == 'n' && $bookeddate == $datee) {
            echo "<td title='Night booked' align='center' bgcolor='black' color='white' valign='middle' height='20px'>". ($datee) . "</td>";
            $displayed = true;
        } else if ($cMonth == $bookedmon && $row['Time'] == 'c' && $bookeddate == $datee) {
            echo "<td title='Completely booked' align='center' bgcolor='red' valign='middle' height='20px'>". ($datee) . "</td>";
            $displayed = true;
        }
    }

    if(!$displayed) {
        if($i < $startday) echo "<td></td>";
        else if ($datee == $toddate && $cMonth == $todmon) echo "<td title='today' align='center' bgcolor='lime' valign='middle' height='20px'>". ($datee) . "</td>";
        else if ($datee != $bookeddate) echo "<td align='center' valign='middle' height='20px'>". ($datee) . "</td>";
        if(($i % 7) == 6 ) echo "</tr>";
    }
}

这是更好,更清洁的方法。

$timestamp = mktime(0,0,0,$cMonth,1,$cYear);
$maxday = date("t",$timestamp);
$thismonth = getdate ($timestamp);
$startday = $thismonth['wday'];
$toddate = date("j");
$todmon = date("n");


const DATE_FREE = 0;
const DATE_DAY_BOOKED = 1;
const DATE_NIGHT_BOOKED = 2;
const DATE_COMPLETELY_BOOKED = 3;
const DATE_TODAY = 4;

for ($i=0; $i<($maxday+$startday); $i++) {
    if(($i % 7) == 0 ) echo "<tr>";

    if($i < $startday) {
        echo "<td></td>"; 
        continue;
    }

    $datee = $i - $startday + 1;
    $dateStatus = DATE_FREE;

    $getr = mysql_query("SELECT * FROM `reservations` WHERE `UserID` = 1");
    while ($row = mysql_fetch_assoc($getr)) {
        $timestamp = strtotime($row['Date']);
        $bookeddate = date("d", $timestamp);

        $bookedmon = date("n", $timestamp);
        if ($cMonth == $bookedmon && $row['Time'] == 'd' && $bookeddate == $datee) {
            $dateStatus = DATE_DAY_BOOKED;
        } else if ($cMonth == $bookedmon && $row['Time'] == 'n' && $bookeddate == $datee) {
            $dateStatus = DATE_NIGHT_BOOKED;
        } else if ($cMonth == $bookedmon && $row['Time'] == 'c' && $bookeddate == $datee) {
            $dateStatus = DATE_COMPLETELY_BOOKED;
        }
    }

    if (DATE_FREE == $dateStatus && $datee == $toddate && $cMonth == $todmon) {
        $dateStatus = DATE_TODAY;
    }

    echo "<td align='center' valign='middle' height='20px'";
    switch($dateStatus) {
        case DATE_DAY_BOOKED:
            echo " title='day booked' bgcolor='orange'";
            break;
        case DATE_NIGHT_BOOKED:
            echo " title='Night booked' bgcolor='black'";
            break;
        case DATE_COMPLETELY_BOOKED:
            echo " title='Completely booked' bgcolor='red'";
            break;
        case DATE_TODAY;
            echo " title='today' bgcolor='lime'";
            break;
    }
    echo ">". ($datee) . "</td>";

    if(($i % 7) == 6 ) echo "</tr>";

}