Отображение запланированных событий - PullRequest
0 голосов
/ 15 декабря 2009

У меня была эта проблема несколько лет назад, и тогда я реализовал «другую логику» для реализации проекта, но сомнения остаются в моей голове, и, надеюсь, с вашей помощью я смогу понять это сейчас.

Предположим, у меня есть некоторые запланированные события в моей базе данных, которые могут появляться или не появляться в течение нескольких дней:

id    event           start          end
-----------------------------------------------
1     fishing trip    2009-12-15     2009-12-15
2     fishCON         2009-12-18     2009-12-20
3     fishXMAS        2009-12-24     2009-12-25

Теперь я хочу отобразить события в календаре, давайте возьмем декабрьский месяц:

for ($day = 1; $day <= 31; $day++)
{
    if (dayHasEvents('2009-12-' . $day) === true)
    {
        // display the day number w/ a link
    }

    else
    {
        // display the day number
    }
}

Какой запрос должна выполнить функция dayHasEvents(), чтобы проверить, есть ли (или нет) события на этот день? Я предполагаю, что SELECT .. WHERE .. BETWEEN имеет больше смысла здесь, но я не знаю, как это реализовать. Я в правильном направлении?

Заранее спасибо!


@ Джеймс:

Допустим, мы находимся 19 декабря :

SELECT *
FROM events
WHERE start >= '2009-12-19 00:00:00'
  AND end <= '2009-12-19 23:59:59'

Должен вернуть событие # 2 , но ничего не возвращает. = \

Ответы [ 3 ]

2 голосов
/ 15 декабря 2009

Вы должны отказаться от этого подхода и забрать все события за данный месяц, так что вам нужно выполнить только один запрос, а не N запросов, где N - количество дней в месяце.

Затем вы можете сохранить возвращенные результаты в многомерном массиве, например:

// assume event results are in an array of objects in $result
$events = array();
foreach ($result as $r) {
    // add event month and day as they key index
    $key = (int) date('j', strtotime($r->start));
    // store entire returned result in array referenced by key
    $events[$key][] = $r;
}

Теперь у вас будет многомерный массив событий за данный месяц, ключом которого будет день. Вы можете легко проверить, существуют ли какие-либо события в данный день, выполнив:

$day = 21;
if (!empty($events[$day])) {
    // events found, iterate over all events
    foreach ($events[$day] as $event) {
        // output event result as an example
        var_dump($event);
    }
}
1 голос
/ 15 декабря 2009

Джеймс имеет правильное представление о выражении SQL. Вы определенно не хотите запускать несколько MySQL SELECT из цикла for. Если daysHasEvents запускает SELECT, это 31 отдельный запрос SQL. Ой! Какой убийца производительности.

Вместо этого загрузите дни месяца, в которых есть события, в массив (используя один SQL-запрос), а затем выполните итерации по дням. Примерно так:

$sql= "SELECT start, end FROM events WHERE start >= '2009-12-01' AND end <= '2009-12-31'";
$r= mysql_query($sql);
$dates= array();
while ($row = mysql_fetch_assoc($r)) {
  // process the entry into a lookup
  $start= date('Y-m-d', strtotime($row['start']));
  if (!isset($dates[$start])) $dates[$start]= array();
  $dates[$start][]= $row;
  $end= date('Y-m-d', strtotime($row['end']));
  if ($end != $start) {
    if (!isset($dates[$end])) $dates[$end]= array();
    $dates[$end][]= $row;
  }
}

// Then step through the days of the month and check for entries for each day:
for ($day = 1; $day <= 31; $day++)
{
    $d= sprintf('2009-12-%02d', $day);
    if (isset($dates[$d])) {
        // display the day number w/ a link
    } else {
        // display the day number
    }
}

Для ваших целей лучше использовать SQL-оператор, который собирает дату начала и количество событий в каждый день. Этот оператор будет работать правильно, только если начальный столбец является столбцом даты без компонента времени:

$sql= "SELECT start, end, COUNT(*) events_count FROM events WHERE start >= '2009-12-01' AND end <= '2009-12-31' GROUP BY start, end";
1 голос
/ 15 декабря 2009

Вы определенно на правильном пути. Вот как бы я это сделал:

SELECT *
FROM events
WHERE start <= '2009-12-01 00:00:00'
  AND end >= '2009-12-01 23:59:59'

И вы, очевидно, просто заменяете эти значения дат днем, когда вы проверяете.

...