简体   繁体   中英

Why is SQL SELECT statement not retrieving relevant dates for PHP calendar?

I'm trying to build an events calendar in PHP and SQL based on an example by David Walsh. His example is quite old and uses functions like mysql_query which are deprecated so I have tried to modernise using PDO. So far I've managed to print out the calendar and am able to select different months and years. I've also successfully created a database connection. The table consists of an id (Auto incremented), title (varchar) and event_date(date). I've populated the table with a few events but I can't seem to retrieve them successfully. I've included the most relevant parts of the code at the top but I've copied the whole code over for context.

$events = array();
try {   $results = $db->query("SELECT title, DATE_FORMAT(event_date,'%Y-%m-%d') AS event_date FROM events WHERE event_date LIKE '$year-$month'");
        echo "<pre>";
        var_dump($results);
} catch (Exception $e) {
    echo "cannot get results!";
    exit;
}

$bookings = $results->fetchAll(PDO::FETCH_ASSOC);

while($row = $bookings) {
    $events[$row['event_date']][] = $row;
}

echo '<pre>';
var_dump($bookings);

object(PDOStatement)#2 (1) {
  ["queryString"]=>
  string(105) "SELECT title, DATE_FORMAT(event_date,'%Y-%m-%d') AS event_date FROM events WHERE event_date LIKE '2014-1'"
}

 array(0) {
    }

<?php 

require('database.php');

/* draws a calendar */
function draw_calendar($month,$year,$events = array()){

    /* draw table */
    $calendar = '<table cellpadding="0" cellspacing="0" class="calendar">';

    /* table headings */
    $headings = array('Sontag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag');
    $calendar.= '<tr class="calendar-row"><td class="calendar-day-head">'.implode('</td><td class="calendar-day-head">',$headings).'</td></tr>';

    /* days and weeks vars now ... */
    $running_day = date('w',mktime(0,0,0,$month,1,$year));
    $days_in_month = date('t',mktime(0,0,0,$month,1,$year));
    $days_in_this_week = 1;
    $day_counter = 0;
    $dates_array = array();

    /* row for week one */
    $calendar.= '<tr class="calendar-row">';

    /* print "blank" days until the first of the current week */
    for($x = 0; $x < $running_day; $x++):
        $calendar.= '<td class="calendar-day-np">&nbsp;</td>';
        $days_in_this_week++;
    endfor;

    /* keep going with days.... */
    for($list_day = 1; $list_day <= $days_in_month; $list_day++):
        $calendar.= '<td class="calendar-day"><div style="position:relative;height:100px;">';
            /* add in the day number */
            $calendar.= '<div class="day-number">'.$list_day.'</div>';

            $event_day = $year.'-'.$month.'-'.$list_day;
            if(isset($events[$event_day])) {
                foreach($events[$event_day] as $event) {
                    $calendar.= '<div class="event">'.$event['title'].'</div>';
                }
            }
            else {
                $calendar.= str_repeat('<p>&nbsp;</p>',2);
            }
        $calendar.= '</div></td>';
        if($running_day == 6):
            $calendar.= '</tr>';
            if(($day_counter+1) != $days_in_month):
                $calendar.= '<tr class="calendar-row">';
            endif;
            $running_day = -1;
            $days_in_this_week = 0;
        endif;
        $days_in_this_week++; $running_day++; $day_counter++;
    endfor;

    /* finish the rest of the days in the week */
    if($days_in_this_week < 8):
        for($x = 1; $x <= (8 - $days_in_this_week); $x++):
            $calendar.= '<td class="calendar-day-np">&nbsp;</td>';
        endfor;
    endif;

    /* final row */
    $calendar.= '</tr>';


    /* end the table */
    $calendar.= '</table>';

    /** DEBUG **/
    $calendar = str_replace('</td>','</td>'."\n",$calendar);
    $calendar = str_replace('</tr>','</tr>'."\n",$calendar);

    /* all done, return result */
    return $calendar;
}

function random_number() {
    srand(time());
    return (rand() % 7);
}

/* date settings */
$month = (int) ($_GET['month'] ? $_GET['month'] : date('m'));
$year = (int)  ($_GET['year'] ? $_GET['year'] : date('Y'));

/* select month control */
$select_month_control = '<select name="month" id="month">';
for($x = 1; $x <= 12; $x++) {
    $select_month_control.= '<option value="'.$x.'"'.($x != $month ? '' : ' selected="selected"').'>'.date('F',mktime(0,0,0,$x,1,$year)).'</option>';
}
$select_month_control.= '</select>';

/* select year control */
$year_range = 7;
$select_year_control = '<select name="year" id="year">';
for($x = ($year-floor($year_range/2)); $x <= ($year+floor($year_range/2)); $x++) {
    $select_year_control.= '<option value="'.$x.'"'.($x != $year ? '' : ' selected="selected"').'>'.$x.'</option>';
}
$select_year_control.= '</select>';

/* "next month" control */
$next_month_link = '<a href="?month='.($month != 12 ? $month + 1 : 1).'&year='.($month != 12 ? $year : $year + 1).'" class="control">Next Month &gt;&gt;</a>';

/* "previous month" control */
$previous_month_link = '<a href="?month='.($month != 1 ? $month - 1 : 12).'&year='.($month != 1 ? $year : $year - 1).'" class="control">&lt;&lt;    Previous Month</a>';


/* bringing the controls together */
$controls = '<form method="get">'.$select_month_control.$select_year_control.'&nbsp;<input type="submit" name="submit" class="btn btn-default" value="Go" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'.$previous_month_link.'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'.$next_month_link.' </form>';

/* get all events for the given month */
$events = array();
try {   $results = $db->query("SELECT title, DATE_FORMAT(event_date,'%Y-%m-%d') AS event_date FROM events WHERE event_date LIKE '$year-$month'");
        echo "<pre>";
        var_dump($results);
} catch (Exception $e) {
    echo "cannot get results!";
    exit;
}

$bookings = $results->fetchAll(PDO::FETCH_ASSOC);

while($row = $bookings) {
    $events[$row['event_date']][] = $row;
}

echo '<pre>';
var_dump($bookings);

echo '<h2 style="float:left; padding-right:30px;">'.date('F',mktime(0,0,0,$month,1,$year)).' '.$year.'</h2>';
echo '<div style="float:left;">'.$controls.'</div>';
echo '<div style="clear:both;"></div>';
echo draw_calendar($month,$year,$events);
echo '<br /><br />';

Besides the LIKE issue

FetchAll get the entire set,so while wont work.Use foreach

foreach ($bookings as $row) {
    $events[$row['event_date']][] = $row;
}

Also in your while you use the assignment operator instead of the comparison ==

I think you forgot a wildcard in your sql query string.

You can try this:

WHERE event_date LIKE '$year-$month%'"

You will do much better if you handle your event_date column as a date rather than as a text field.

Try this query:

SELECT title, 
       DATE_FORMAT(event_date,'%Y-%m-%d') AS event_date 
  FROM events
 WHERE event_date >= DATE(DATE_FORMAT(NOW(),'%Y-%m-01'))
   AND event_date <  DATE(DATE_FORMAT(NOW(),'%Y-%m-01')) + INTERVAL 1 MONTH

This will find all the event_date values in the present month, and at the same time will use the MySQL index on event_date for searching if you have one.

If you want last month's events, you can do this instead.

 WHERE event_date >= DATE(DATE_FORMAT(NOW(),'%Y-%m-01')) - INTERVAL 1 MONTH
   AND event_date <  DATE(DATE_FORMAT(NOW(),'%Y-%m-01'))

Here's an introduction to this topic. http://www.plumislandmedia.net/mysql/sql-reporting-time-intervals/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM