PHP实现日历功能核心是利用内置的日期时间函数计算月份的总天数、当月第一天是星期几,再结合HTML排版生成日历表格,同时可以通过参数传递实现月份切换、日期点击等交互效果。

基础日历生成逻辑
生成日历首先要明确三个核心参数:当前年份、当前月份、需要切换的目标年份和月份。我们可以通过date()函数获取当前日期信息,也可以通过GET参数接收用户传递的年份和月份。
核心日期计算函数
PHP的date()和mktime()函数是日历计算的基础,常用用法如下:
date('t', mktime(0,0,0,$month,1,$year)):获取指定年份指定月份的总天数date('w', mktime(0,0,0,$month,1,$year)):获取指定月份第一天是星期几,0代表周日,1代表周一,以此类推mktime(0,0,0,$month-1,1,$year):获取上个月的起始时间戳mktime(0,0,0,$month+1,1,$year):获取下个月的起始时间戳
完整日历生成代码示例
以下代码实现了基础日历渲染,支持通过URL参数year和month切换月份,同时标记当前日期:
<?php
// 获取当前年份和月份,默认使用当前系统时间
$year = isset($_GET['year']) ? intval($_GET['year']) : date('Y');
$month = isset($_GET['month']) ? intval($_GET['month']) : date('m');
// 计算当前月总天数
$totalDays = date('t', mktime(0, 0, 0, $month, 1, $year));
// 计算当前月第一天是星期几,0是周日
$firstDayOfWeek = date('w', mktime(0, 0, 0, $month, 1, $year));
// 计算上个月的年份和月份
$prevMonthTime = mktime(0, 0, 0, $month - 1, 1, $year);
$prevYear = date('Y', $prevMonthTime);
$prevMonth = date('m', $prevMonthTime);
// 计算下个月的年份和月份
$nextMonthTime = mktime(0, 0, 0, $month + 1, 1, $year);
$nextYear = date('Y', $nextMonthTime);
$nextMonth = date('m', $nextMonthTime);
// 当前系统日期,用于标记今日
$todayYear = date('Y');
$todayMonth = date('m');
$todayDay = date('d');
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>PHP日历</title>
<style>
.calendar {
width: 400px;
border: 1px solid #ccc;
font-family: Arial, sans-serif;
}
.calendar-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
background-color: #f0f0f0;
}
.calendar-header a {
text-decoration: none;
color: #333;
padding: 5px 10px;
border: 1px solid #ccc;
background-color: #fff;
}
.calendar-week {
display: flex;
background-color: #e8e8e8;
}
.calendar-week div {
width: 14.28%;
text-align: center;
padding: 8px 0;
font-weight: bold;
}
.calendar-days {
display: flex;
flex-wrap: wrap;
}
.calendar-days div {
width: 14.28%;
height: 50px;
box-sizing: border-box;
border: 1px solid #eee;
display: flex;
align-items: center;
justify-content: center;
}
.today {
background-color: #ffcccc;
border-radius: 50%;
}
.other-month {
color: #ccc;
}
</style>
</head>
<body>
<div class="calendar">
<div class="calendar-header">
<a href="?year=<?php echo $prevYear;?>&month=<?php echo $prevMonth;?>">上个月</a>
<span><?php echo $year;?>年<?php echo $month;?>月</span>
<a href="?year=<?php echo $nextYear;?>&month=<?php echo $nextMonth;?>">下个月</a>
</div>
<div class="calendar-week">
<div>日</div>
<div>一</div>
<div>二</div>
<div>三</div>
<div>四</div>
<div>五</div>
<div>六</div>
</div>
<div class="calendar-days">
<?php
// 输出上个月末尾的日期补全空白
if ($firstDayOfWeek > 0) {
$prevMonthTotalDays = date('t', mktime(0, 0, 0, $month - 1, 1, $year));
for ($i = $prevMonthTotalDays - $firstDayOfWeek + 1; $i <= $prevMonthTotalDays; $i++) {
echo '<div class="other-month">' . $i . '</div>';
}
}
// 输出当前月的所有日期
for ($day = 1; $day <= $totalDays; $day++) {
$isToday = ($year == $todayYear && $month == $todayMonth && $day == $todayDay);
$class = $isToday ? 'today' : '';
echo '<div class="' . $class . '">' . $day . '</div>';
}
// 输出下个月开头的日期补全最后一行
$lastDayOfWeek = date('w', mktime(0, 0, 0, $month, $totalDays, $year));
if ($lastDayOfWeek < 6) {
$nextDays = 6 - $lastDayOfWeek;
for ($i = 1; $i <= $nextDays; $i++) {
echo '<div class="other-month">' . $i . '</div>';
}
}
?>
</div>
</div>
</body>
</html>日历交互扩展实现
基础日历生成后,还可以扩展更多交互功能,比如点击日期触发事件、显示日期对应的事件内容等:
日期点击交互
给日期元素添加点击事件,可以通过JavaScript实现,也可以在PHP渲染时直接给日期添加链接,示例代码如下:
<?php
// 在循环输出当前月日期时,给日期添加点击链接
for ($day = 1; $day <= $totalDays; $day++) {
$isToday = ($year == $todayYear && $month == $todayMonth && $day == $todayDay);
$class = $isToday ? 'today' : '';
// 点击日期跳转到事件页面,传递年月日参数
echo '<div class="' . $class . '"><a href="event.php?year=' . $year . '&month=' . $month . '&day=' . $day . '" style="text-decoration:none;color:#333;">' . $day . '</a></div>';
}
?>日期事件标记
如果需要标记有事件的日期,可以先从数据库或数组中读取事件日期,渲染时判断当前日期是否在事件日期列表中,添加对应标记:
<?php
// 假设从数据库获取的事件日期数组
$eventDays = [1, 5, 12, 20];
for ($day = 1; $day <= $totalDays; $day++) {
$isToday = ($year == $todayYear && $month == $todayMonth && $day == $todayDay);
$hasEvent = in_array($day, $eventDays);
$class = $isToday ? 'today' : '';
$eventMark = $hasEvent ? '<span style="color:red;font-size:12px;">●</span>' : '';
echo '<div class="' . $class . '">' . $day . $eventMark . '</div>';
}
?>注意事项
开发PHP日历时需要注意几个常见问题:一是月份和年份的边界处理,比如1月的上个月是去年的12月,12月的下个月是明年的1月,代码中通过mktime()函数可以自动处理这种边界情况;二是日期参数的合法性校验,避免用户传递非法的年份和月份导致计算出错;三是样式适配,不同月份的周数不同,需要保证日历表格的排版整齐,不会出现布局错乱的问题。
PHPcalendardate_functionHTMLCSS修改时间:2026-06-04 05:51:40