Создание PHP календаря

В этой статье я расскажу как создать функциональный календарь с использованием PHP. Около года назад мне поручили сделать календарь событий на одном сайте. Заказчик не очень жаловал javascript или ajax, поэтому настоял на использовании PHP. Это было довольно интересный опыт. Мне пришлось забыть свои мечты о быстром выполнении заказа с использованием jQuery datepicker. Я уже приготовился к тому, что мне предстоит тяжелая работа. Потом меня осенило. Ведь календарь, по сути, является ни чем иным как системой циклических чисел. Чем больше я об этом думал, тем легче мне начинала казаться задача. В конце концов, после небольшого исследования о функциях даты PHP, я придумал способ, который действительно сработал. Рабочий пример можно скачать здесь.

Начнем с установки нескольких переменных среды. Очевидно, что нам необходимо знать URL нашего скрипта, и, поскольку мы работаем с календарем, нам нужна дата, от которой мы будем отталкиваться. Нам нужно проверить, указывает ли назначенная на наш URL переменная на конкретный год, месяц и день. Если нет, то мы начнем с сегодняшней даты.

  1. <?php
  2. // местоположение скрипта
  3. $self = $_SERVER['PHP_SELF'];
  4.  
  5. // проверяем, если в переменная month была установлена в URL-адресе,
  6. //либо используем PHP функцию date(), чтобы установить текущий месяц.
  7. if(isset($_GET['month']))
  8. $month = $_GET['month'];
  9. elseif(isset($_GET['viewmonth']))
  10. $month = $_GET['viewmonth'];
  11. else $month = date('m');
  12.  
  13. // Теперь мы проверим, если переменная года устанавливается в URL,
  14. //либо использовать PHP функцию date(),
  15. //чтобы установить текущий год, если текущий год не установлен в URL-адресе.
  16. if(isset($_GET['year']))
  17. $year = $_GET['year'];
  18. elseif(isset($_GET['viewyear']))
  19. $year = $_GET['viewyear'];
  20. else $year = date('Y');
  21.  
  22. ?>

Следующая задача будем немного сложнее, чем кажется, когда мы впишем ее в код. Мне нужно было изменить год, когда наступал следующий за декабрем месяц. Позже вы увидите, что то же самое нужно будет делать и на тот случай, если календарь будет просматриваться в обратную сторону.

  1. <?php
  2. if($month == '12')
  3. $next_year = $year + 1;
  4. else $next_year = $year;
  5.  
  6. ?>

Теперь давайте используем установленные выше значения месяца и года, чтобы выяснить, на какой день выпадет начало нового месяца. К счастью, mktime идеально подойдет для этой задачи. Если кто не знает, в mktime передаются следующие значения: Час, Минута, Секунда, Месяц, День и Год. Затем он выдает временную метку Unix для этого момента времени.

  1.  
  2. <?php
  3.  
  4. $Month_r = array(
  5. "1" => "январь",
  6. "2" => "февраль",
  7. "3" => "март",
  8. "4" => "апрель",
  9. "5" => "май",
  10. "6" => "июнь",
  11. "7" => "июль",
  12. "8" => "август",
  13. "9" => "сентябрь",
  14. "10" => "октябрь",
  15. "11" => "ноябрь",
  16. "12" => "декабрь");
  17.  
  18. $first_of_month = mktime(0, 0, 0, $month, 1, $year);
  19.  
  20. // Массив имен всех дней в неделю
  21. $day_headings = array('Sunday', 'Monday', 'Tuesday',
  22. 'Wednesday', 'Thursday', 'Friday', 'Saturday');
  23.  
  24. $maxdays = date('t', $first_of_month);
  25. $date_info = getdate($first_of_month);
  26. $month = $date_info['mon'];
  27. $year = $date_info['year'];
  28.  
  29. // Если текущий месяц это январь,
  30. //и мы пролистываем календарь задом наперед число,
  31. //обозначающее год, должно уменьшаться на один.
  32.  
  33. if($month == '1'):
  34. $last_year = $year-1;
  35. else: $last_year = $year;
  36. endif;
  37.  
  38. // Вычитаем один день с первого дня месяца,
  39. //чтобы получить в конец прошлого месяца
  40. $timestamp_last_month = $first_of_month - (24*60*60);
  41. $last_month = date("m", $timestamp_last_month);
  42.  
  43. // Проверяем, что если месяц декабрь,
  44. //на следующий месяц равен 1, а не 13
  45. if($month == '12')
  46. $next_month = '1';
  47. else $next_month = $month+1;
  48.  
  49. ?>

Как видите, мы потратили достаточно много времени на то, чтобы убедиться, что мы знаем наше положение во времени и можем влиять на то, что произойдет, когда значения дней, лет и месяцев будут уменьшаться или увеличиваться при просмотре календаря. Важно помнить, что при работе с датами всегда полезно устанавливать значения по умолчанию, прежде чем приступать к созданию кода. Нельзя точно знать, что вам понадобиться, но по ходу выполнения задачи вам почти наверняка нужно будет узнать текущий день, месяц и год. Мы снова используем функцию даты() в PHP и mktime(), чтобы точно манипулировать числами. Далее мы начинаем чертить календарь.

  1.  
  2. <?php
  3. $calendar = "
  4. <div class=\"block-on-center\">
  5. <table width='390px' height='280px' style='border: 1px solid #cccccc';>
  6. <tr style='background: #5C8EB3;'>
  7. <td colspan='7' class='navi'>
  8. <a style='margin-right: 50px; color: #ffffff;'
  9. href='$self?month=".$last_month."&year=".$last_year."'><<</a>
  10. ".$Month_r[$month]." ".$year."
  11. <a style='margin-left: 50px; color: #ffffff;'
  12. href='$self?month=".$next_month."&year=".$next_year."'>>></a>
  13. </td>
  14. </tr>
  15. <tr>
  16. <td class='datehead'>Пн</td>
  17. <td class='datehead'>Вт</td>
  18. <td class='datehead'>Ср</td>
  19. <td class='datehead'>Чт</td>
  20. <td class='datehead'>Пт</td>
  21. <td class='datehead'>Сб</td>
  22. <td class='datehead'>Вс</td>
  23. </tr>
  24. <tr>";
  25. ?>

Выше мы сделали заголовок таблицы и ссылки навигации, чтобы переходить вперед и назад по месяцам и годам в календаре. Теперь мы печатаем дни, выделяя сегодняшнюю дату. Каждый день – это ссылка на тот день, на который мы можем перейти. Теперь будет просто создать систему событий, так как день, месяц и год, на которые вы кликаете, указывает на URL, благодаря чему вы можете просматривать установки и показывать события согласно этому.

  1. <?php
  2.  
  3. // очищаем имя класса css
  4. $class = "";
  5.  
  6. $weekday = $date_info['wday'];
  7.  
  8. // Приводим к числа к формату 1 - понедельник, ..., 6 - суббота
  9. $weekday = $weekday-1;
  10. if($weekday == -1) $weekday=6;
  11.  
  12. // станавливаем текущий день как единица 1
  13. $day = 1;
  14.  
  15. // выводим ширину календаря
  16. if($weekday > 0)
  17. $calendar .= "<td colspan='$weekday'> </td>";
  18.  
  19. while($day <= $maxdays)
  20. {
  21. // если суббота, выволдим новую колонку.
  22. if($weekday == 7) {
  23. $calendar .= "</tr><tr>";
  24. $weekday = 0;
  25. }
  26.  
  27. $linkDate = mktime(0, 0, 0, $month, $day, $year);
  28.  
  29. // проверяем, если распечатанная дата является сегодняшней датой.
  30. //если так, используем другой класс css, чтобы выделить её
  31. if((($day < 10 and "0$day" == date('d')) or ($day >= 10 and "$day" == date('d')))
  32. and (($month < 10 and "0$month" == date('m'))
  33. or ($month >= 10 and "$month" == date('m'))) and $year == date('Y'))
  34. $class = "caltoday";
  35.  
  36. //в противном случае, печатаем только ссылку на вкладку
  37. else {
  38. $d = date('m/d/Y', $linkDate);
  39.  
  40. $class = "cal";
  41. }
  42.  
  43. //помечаем выходные дни красным
  44. if($weekday == 5 || $weekday == 6) $red='style="color: red" ';
  45. else $red='';
  46.  
  47. $calendar .= "
  48. <td class='{$class}'><span ".$red.">{$day}</span>
  49. </td>";
  50. $day++;
  51. $weekday++;
  52. }
  53.  
  54. if($weekday != 7)
  55. $calendar .= "<td colspan='" . (7 - $weekday) . "'> </td>";
  56.  
  57. // выводим сам календарь
  58. echo $calendar . "</tr></table>";
  59.  
  60. ?>

Хотите - верьте, хотите – нет, но на этом все. Теперь можно кликать на каждый день календаря, переходить на месяцы и годы, нажимая на стрелки рядом с названием месяца в заголовке таблицы. Сегодняшняя дата отличается от всех остальных своим классом CSS, поэтому ее можно стилизовать по своему усмотрению, и у нас получился довольно гибкий календарь. В завершение хочу включить в наш проект небольшую форму, которая позволит вам переходить на любой месяц любого года на двадцать лет вперед. Также хочу предложить ссылку для перехода на текущий месяц. Код очень простой:

  1. <?php
  2. $months = array(
  3. 'Январь',
  4. 'Февраль',
  5. 'Март',
  6. 'Апрель',
  7. 'Май',
  8. 'Июнь',
  9. 'Июль',
  10. 'Август',
  11. 'Сентябрь',
  12. 'Октябрь',
  13. 'Ноябрь',
  14. 'Декабрь');
  15.  
  16. echo "<form style='float: right; margin-right: 10px;' action='$self' method='get'>
  17. <select name='month'>";
  18.  
  19. for($i=0; $i<=11; $i++) {
  20. echo "<option value='".($i+1)."'";
  21. if($month == $i+1)
  22. echo "selected = 'selected'";
  23. echo ">".$months[$i]."</option>";
  24. }
  25.  
  26. echo "</select>";
  27. echo "<select name='year'>";
  28.  
  29. for($i=date('Y'); $i<=(date('Y')+20); $i++)
  30. {
  31. $selected = ($year == $i ? "selected = 'selected'" : '');
  32.  
  33. echo "<option value=\"".($i)."\"$selected>".$i."</option>";
  34. }
  35.  
  36. echo "</select><input type='submit' value='смотреть' /></form>";
  37.  
  38. if($month != date('m') || $year != date('Y'))
  39. echo "<a style='float: left; margin-left: 10px; font-size: 12px; padding-top: 5px;'
  40. href='".$self."?month=".date('m')."&year=".date('Y')."'><< Вернуться к текущей дате</a>";
  41. echo "</div>";
  42. ?>
php календарь

Понравилась статья?

Прочитано 10748 раз

Добавить комментарий


Защитный код
Обновить