2015-06-27 224 views
0

我有以下條目的數據庫:PHP MySQL和嵌套循環

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>"; 
} 

的問題是,它示出了在數據庫中的第一日兩次,而另一個日期顯示只有1次。我如何設法只顯示一次這兩個日期。

您可能需要在您的最後運行php代碼。

+0

第一關:** [停止使用'mysql_ *'功能(http://stackoverflow.com/q/12859942/2302862)** – Siguza

+0

客戶端只需要MySQL,必須堅持它。 – Saifi

+0

你意識到你正在執行相同的查詢並且一遍又一遍地重複使用同一個數據集?這是非常低效的。你必須翻開你的循環 - 運行sql查詢一次,遍歷一次數據集並打印具有特定顏色的日期。 – dmitreyg

回答

0

該問題是由於使用超出範圍的$ bookeddate變量或弄亂大括號而引起的。

這部分代碼是你,而($行= 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>"; 

} 
+0

但是如果代碼包含在while循環中,那麼每個日期都會顯示兩次。 – Saifi

+0

那麼如何完全刪除它? – Siguza

+0

它不應該。其實你不應該在while循環中輸出任何東西。更好的方法是檢查日期狀態並將其保存到變量中,然後將回聲僅放置在for循環內的一個位置。我會在我的答案中發佈它。 – pamelus