1

mySQL 中的表保存未来几年的酒店预订。

每行包含 id、start_date、end_date 和 status。start_date 包含代表签入日期的日期类型,end_date 是签出日期。

我想检索一组单独的日期,以便我可以循环浏览一年日历并显示下一年的免费日期和保留日期。

由于退房时间较早,酒店可以在 end_date 再次出租房间,因此 end_date 本身不需要包括在内。

例子

ID | start_date |  end_date  | status

1  | 03/15/2014 | 03/18/2014 |  Paid
2  | 05/22/2014 | 05/25/2014 |  Deposit
3  | 08/12/2014 | 08/13/2014 |  Paid

并排列:

 $months_arry = array(1 => '03/15/2014', 1 => '03/16/2014', 1 => '03/17/2014',
 1 => '05/22/2014', 1 => '05/23/2014', 1 => '05/24/2014', 1 => '08/12/2014');

由于日历的所有 12 个月都垂直显示在同一页面上,因此最简单的方法是根据数组检查每个日期,以了解它应该是绿色表示空置还是红色表示占用。

在 sql server 上的 asp 3.0 中,我刚刚创建了一个记录集 rs,其中包含“

SELECT start_date, end_date from HotelBookings where start_date >= '2013-12-31'
 AND enddate <= '2015-01-01' ORDER BY start_date ASC"

然后 .. 直到 rs.EOF 循环 .. 在里面

循环我将检索 start_date 和 end_date 并循环它们直到两者相等,同时在构建单个日期数组时向 start_date 添加 + 1。

我在寻找答案时发现了这个例子,但它看起来很丑而且不优雅

<?php
// Make a MySQL Connection
$query = "SELECT * FROM example"; 

$result = mysql_query($query) or die(mysql_error());


while($row = mysql_fetch_array($result)){
    echo $row['name']. " - ". $row['age'];
    echo "<br />";
}
?>
4

2 回答 2

1

小心在其主体中包含SQL 语句的循环,因为 SQL 将运行n次,其中n是循环主体执行的次数。这可能是非常低效的。

DateTime 对象在这里可以成为您的朋友。

// note that an array with the same key pointing to more than one value will have its values override eachother.
// array(1 => 'foo', 1 => 'bar') is generally not a good idea.
$months_array = array('03/15/2014', '03/16/2014', '03/17/2014', '05/22/2014', '05/23/2014', '05/24/2014', '08/12/2014');

// covert dates to check to DateTimes so that we can perform comparisons on them
$to_check_array = array_map(function ($value) { return new DateTime($value); } , $months_array);

// get all taken date ranges
$result = mysql_query("SELECT `start_date`, `end_date` FROM `date_table`");

// loop over all taken date ranges
while ($row = mysql_fetch_row($result))
{
  // convert dates to DateTimes to perform comparisons on them
  $start_date = new DateTime($row[0]);
  $end_date   = new DateTime($row[1]);

  // check each date against all taken ranges
  foreach ($to_check_array as $cur)
  {
    if ($cur >= $start_date and $cur < $end_date)
    {
      $taken = $cur->format('m/d/Y');
      echo "{$taken} is taken.<br>";
    }
  }
}

我认为这应该可以解决您的问题。至于优雅,嗯,优雅在 PHP 中并不丰富。这是一种被来自不同背景的许多人混合在一起的语言。它是一种漂亮而简单、不断发展的语言,但不是我认为优雅的语言。如果您需要使用 PHP 并且正在寻找一些优雅的 Web 应用程序,我会推荐像 CodeIgniter 或 Laravel 这样的框架。后者尤其优雅。

此外,请小心使用旧mysql_函数,因为这些函数将从即将发布的 PHP版本中删除。您可能想研究 mysqli 或 PDO。

于 2013-09-05T11:13:17.340 回答
0

尽管这不是真正的答案(我不会将其标记为答案),但这就是我解决问题的方法。

我希望有一种方法可以做到这一点,而不必在循环中执行所有这些循环,而只需直接从 mysql 获取最终结果(日期数组)

这将在预订酒店房间时从 mysql 中选择所有日期范围,然后将范围转换为数组中的单个日期。因此,最终结果是一个唯一的排序数组,其中包含今天预订酒店房间的日期之后的所有日期。

<?php
$current_date_t = date('Y-m-d');
$current_date = new DateTime($current_date_t);

// Make a MySQL Connection

$query = "SELECT from_date, to_date FROM t_booking_data where from_date >= '" . $current_date . "' ";

$result = mysql_query($query) or die(mysql_error());
$booked_days_array = array();

while ($row = mysql_fetch_array($result))
{
    $startDate_t = $row['from_date'];
    $startDate = new DateTime($startDate_t);
    $endDate_t = $row['to_date'];
    $endDate = new DateTime($endDate_t);

    while ($startDate < $endDate)
    {
        array_push($booked_days_array, $startDate->format('Y-m-d'));
        $startDate->modify('+1 day');
    }
}
$booked_days_array = array_unique($booked_days_array);
sort($booked_days_array);
?>
于 2013-09-14T10:50:36.550 回答