2014-06-22 24 views
0

大家好日子,根據預訂系統中的可用房間打印HTML表格

我試圖打印一個HTML表格;給定兩個日期(例如7月1日至7月31日),它將在標題上打印日期。然後,每一排將成爲一個房間。 然後,當某個房間在當天預訂時,單元格將具有紅色背景色,如果不是,則它將保持白色。

我在IF中迷路了,看看房間是否應該打印紅色。 到目前爲止,我得到這樣的輸出:http://jsfiddle.net/KatsuroKurosaki/kCkJD/

,我試圖實現這一目標之一:http://jsfiddle.net/KatsuroKurosaki/kCkJD/1/

基於數據庫查詢輸出:

SELECT idsRoom, checkin, checkout 
FROM bookings 
WHERE checkout >= '2014-07-01' AND checkin <= '2014-07-31' 

+---------+------------+------------+ 
| idsRoom | checkin | checkout | 
+---------+------------+------------+ 
| 2  | 2014-06-27 | 2014-07-02 | 
| 4  | 2014-07-08 | 2014-07-09 | 
| 6,7,8 | 2014-07-18 | 2014-07-22 | 
| 14  | 2014-07-31 | 2014-08-02 | 
+---------+------------+------------+ 
4 rows in set (0.00 sec) 

是的,每個預約有一個簽入和一個結帳,以及它必須包含至少一個房間,或更多(這就是爲什麼ID 6,7,8)。我使用PHP 5.5.13,MySQLi準備語句和Maria DB 10.0.12。 這是PHP代碼片段,將打印輸出表:

<?php 
/* This will be the received POST date in the future */ 
$desdeP = "2014-07-01"; 
$hastaP = "2014-07-31"; 

/* Database Connection and DateTime objects */ 
$conn = new MySQLi("localhost","user","password","database"); //Seriusly? Nope ;) 
$desde = DateTime::createFromFormat("Y-m-d",$desdeP); 
$hasta = DateTime::createFromFormat("Y-m-d",$hastaP); 
?> 
<!-- Table with date headers --> 
<table border="1" cellpadding="0" cellspacing="0" style="min-width:100%;min-height:100%;"> 
<tr> 
    <td>&nbsp;</td> 
    <?php 
    while($desde<=$hasta){ 
     echo '<td>'.$desde->format("d-m-Y").'</td>'; 
     $desde->modify("+1Day"); 
    } 
    ?> 
</tr> 
<?php 
/* Query all the rooms */ 
$stmt = $conn->prepare("SELECT id, name FROM rooms ORDER BY id;"); 
$stmt->execute(); 
$rooms = $stmt->get_result()->fetch_all(MYSQLI_ASSOC); 
$stmt->close(); 

/* Query all the bookings in the given dates */ 
$stmt = $conn->prepare("SELECT idsRoom, checkin, checkout 
FROM bookings 
WHERE checkout >= ? AND checkin <= ?;"); 
$stmt->bind_param("ss", 
    $desdeP, 
    $hastaP); 
$stmt->execute(); 
$bookings = $stmt->get_result()->fetch_all(MYSQLI_ASSOC); 
$stmt->close(); 

foreach($rooms as $k=>$v){ // Every row is a room 
    echo '<tr>'; 
    echo '<td>'.$v['name'].'</td>'; 
    $desde = DateTime::createFromFormat("Y-m-d",$desdeP); 
    $hasta = DateTime::createFromFormat("Y-m-d",$hastaP); 
    while($desde<=$hasta){ // For every row, check in the bookings list if available or not 
     echo '<td'; 
     foreach ($bookings as $k2=>$v2){ 
      $checkin = DateTime::createFromFormat("Y-m-d",$v2['checkin']); 
      $checkout = DateTime::createFromFormat("Y-m-d",$v2['checkout']); 
      /* HERE remains my question: What mega IF do I need to paint background in red if the room is not available? */ 
      if((strpos(",".$v2['idsRoom'].",",",".$v['id'].",")!==false) && 
       ($checkin < $hasta && $checkout > $desde) && 
       ($checkin >= $desde && $checkout <= $hasta) 
      ){ 
       echo ' style="background-color:red;"'; 
      } 
     } 
     echo '>&nbsp;</td>'; 
     $desde->modify("+1Day"); 
    } 
    echo '</tr>'; 
} 
$conn->close(); 
?> 
</table> 

感謝所有提前,希望能找到一些幫助吧〜

商祺!

+1

您似乎有一列名爲'idsRoom'的逗號分隔值。在這種情況下,最有效的解決方案包括一罐汽油和一些火柴。 – Strawberry

+0

是的,這是我的解決方案(現在)來存儲預訂和哪些房間與每個預訂相關聯。這是一個很好的解決方案,還是可以改進的? –

+0

這是一個**糟糕的**解決方案。見正常化。 – Strawberry

回答

0

因爲你$desde在你while循環正在運行的日期,所以你應該做的檢查

如果$ desde爲$簽入和$結帳內,然後房間被封鎖 (紅色)

因此,通過使用這種邏輯,這是你需要的唯一條件:

if ((strpos(",".$v2['idsRoom'].",",",".$v['id'].",")!==false) && 
    ($checkin <= $desde && $checkout > $desde) 
){ 
    echo ' style="background-color:red;"'; 
} 

我在本地主機上運行了它,它在您的示例中以您想要的方式工作。希望能幫助到你。

+1

哦,我的魔杖...工作就像一個魅力!非常感謝你! :D現在看到這個非常簡單和整潔的解決方案,我感到羞愧。 祝您有個美好的一天^^ –

0

在快速查看問題後,我注意到您在ID列中有逗號分隔的值。這肯定會給你帶來麻煩,並且會在未來給你帶來更多麻煩。我不是數據庫設計專家,當我開始編程時,我正在做同樣的事情。我想要做一些快速簡單的事情,沒有太多的關係麻煩,它總是變成一團糟,所以最終必須從頭開始,並適當地做。

這種設計反模式會使查詢困難得多,而且,您必須編寫大量代碼才能重新創建丟失的數據庫的內置功能(您已經開始這樣做,strpos(",".$v2['idsRoom'].",",",".$v['id'].",")!==false) 。

我花了一些時間來重寫例子。對於日期範圍,我使用DatePeriod類。它可以在foreach循環中使用,因此它適用於日曆等。此外,這裏有兩個相關數組($rooms$bookings),它們與示例中的數組相同。在$bookings陣列來分隔idsRoom值,它看起來像轉換後:

 
Array 
(
    [0] => Array (...) 
    [1] => Array (...) 
    [2] => Array 
     (
      [idsRoom] => 6 
      [checkin] => 2014-07-18 
      [checkout] => 2014-07-22 
     ) 

    [3] => Array 
     (
      [idsRoom] => 7 
      [checkin] => 2014-07-18 
      [checkout] => 2014-07-22 
     ) 

    [4] => Array 
     (
      [idsRoom] => 8 
      [checkin] => 2014-07-18 
      [checkout] => 2014-07-22 
     ) 

    [5] => Array (...) 
) 

最後,循環輸出表:

<?php 

$range = new DatePeriod(new DateTime("2014-07-01"), new DateInterval('P1D'), new DateTime("2014-08-01")); 

$rooms = array_map(function($k, $v) { return array('name' => $v, 'id' => $k); }, range(1, 30), array_merge(range(101, 110), range(201, 210), range(301, 310))); 

$bookings_original = array( 
    array('idsRoom' => '2', 'checkin' => '2014-06-27', 'checkout' => '2014-07-02'), 
    array('idsRoom' => '4', 'checkin' => '2014-07-08', 'checkout' => '2014-07-09'), 
    array('idsRoom' => '6,7,8','checkin' => '2014-07-18', 'checkout' => '2014-07-22'), 
    array('idsRoom' => '14', 'checkin' => '2014-07-31', 'checkout' => '2014-08-02') 
); 

$bookings = array(); 
foreach($bookings_original as $item) { 
    foreach(explode(',', $item['idsRoom']) as $room) 
     $bookings[] = array_merge($item, array('idsRoom' => $room)); 
} 

?> 
<table border="1" cellpadding="0" cellspacing="0" style="min-width:100%;min-height:100%;"> 
    <tr> 
     <td>&nbsp;</td> 
     <?php foreach($range as $date) : ?> 
     <td><?php echo $date->format("d-m-Y"); ?></td> 
     <?php endforeach; ?> 
    </tr> 
<?php 

foreach($rooms as $room) { 
    echo "<tr><td>$room[name]</td>" . PHP_EOL; 

    foreach($range as $date) { 
     if (
      array_filter($bookings, function($booking) use ($room, $date) { 
       return $booking[ 'idsRoom' ] == $room['id'] && $booking['checkin'] <= $date->format("Y-m-d") && $booking['checkout'] > $date->format("Y-m-d"); 
      }) 
     ) 
      echo '<td style="background-color:red;"></td>' . PHP_EOL; 
     else 
      echo '<td></td>' . PHP_EOL; 
    } 
    echo '</tr>'; 
} 

?> 
</table> 

這裏是一個booking design example,可以幫助你與數據庫和關係之間表。

+0

我明白了......一種解決問題的方式。感謝DatePeriod和DateInterval示例:D我真的很感激它。我會看看你的代碼並實現你的功能(首先必須理解它:P)謝謝! –