php之日历项目实战经验

  1. 1. 第一个问题:制作日历
    1. 1.1. php代码格式的建立
    2. 1.2. date函数获取当前系统时间
    3. 1.3. strtotime函数获取时间戳
    4. 1.4. switch语句判断年月份
    5. 1.5. html5标签构建日历框架
    6. 1.6. for语句与if语句判断输出
    7. 1.7. 完整代码
  2. 2. 第二个问题:显示一年所有日历
    1. 2.1. 使用for循环进行遍历
    2. 2.2. 完整代码
  3. 3. 第三个问题:改变日历年份
    1. 3.1. 完整代码
  4. 4. 总结

本次文章所涉及的知识有CSS样式表、html5标签、PHP(date函数、strtotime函数、switch语句、for循环语句、if条件判断语句).

首先开始,我们来看一下题目:

“使用PHP中基本语法制作出一个类型windows日历那样的日历,之后再原有代码的基础上制作出一年之中12个月份的全部日历,最后再通过该日历去对不同的年份时间日历进行显示”。

第一个问题:制作日历

php代码格式的建立

首先先建立一个PHP中代码的格式

1
<?php?>

date函数获取当前系统时间

之后如果我们要去识别系统上的时间,所以我们将使用date函数

1
2
$year = date('Y');
$month = date('n');

通过创建date函数语句去识别系统中的年和月,之后我们需要知道的是一个日历中我们首先是不是要知道一个月份中的第一天,之后后面的通过该月的第一天去对某个月份的日历中星期与日相对应,所以这时候需要去创建一个变量名为date的变量去存储该月份中第一天的时间。

1
$date = "$year-$month-1";

strtotime函数获取时间戳

之后是不是需要去创建一个strtotime函数去获取该月中第一天的时间戳

strtotime函数是通过1970年1月1日算起的一个获取时间戳的函数

1
$str = strtotime($date);

通过时间戳我们可以获得某月中第一天为星期几的数字值

1
$fristday = date('w',$str);

switch语句判断年月份

之后我们还有一个问题,就是在一年之中闰年和非闰年中2月份的天数是不同的,所以这时候需要设计一个可以判断是否为润年的代码,已知闰年的判断是①$year能被4整除且不能被100整除则为非闰年②$year能被400整除的是闰年,所以

1
2
3
4
5
6
7
8
switch ($month) {
case 2 : $days = ($year % 400 == 0 || ($year % 4 ==0 && $year % 100 !=0))? 29 : 28 ; break ; //计算当年二月是否为闰年,是就为29天
case 4 :
case 6 :
case 9 :
case 11 : $days = 30 ; break ;
default: $days = 31; //除了4、6、9、11月其他月份为31天
}

html5标签构建日历框架

通过switch语句去进行判断,判断系统的年份去判断该年是否为闰年,并且通过识别系统当前月份而去对该月份中天数进行判断。之后我们现在就该设计日历中类似windows10那样的日历框架(不知道的点击你电脑右下角的时间,没有win10的自己去装一个,实在不想装win10或者根本没有电脑百度总会了吧)附链接百度

1
2
3
4
5
6
7
8
echo "<table width = '366' border = '0' cellpading = '0' cellspacing = '2' align='center'>"; //输出表格,宽度设置为366
echo "<caption>下面是$year$month 月的日历</caption>"; //以表格标题行所在的行标记
echo "<tr align='center'>";
echo "<th width = '50' height = '40'> 一</th> <th width = '50'>二</th>";
echo "<th width = '50' > 三 </th> <th width = '50'>四</th>";
echo "<th width = '50'> 五 </th> <th width = '50'>六</th>";
echo "<th width = '50' > 日 </th> "; //输出标题行单元格及内容
echo "</th><tr>"; //输出标题行结束标记和第一个内容行开始的标记

通过表格来设计日历的框架,首先我们要先知道cellspacing是表格单元格间距设置为2像素,因为有八个边框所以总的width像素为16px,之后的350px我们将用来对日历中的列(每一列50px)进行设计,设计出类似windwos10日历中等宽等高的表格。

注意:我们这一步的目的是需要计算出日历中每一格的宽度和高度,并对单元格间距之间也要进行计算,保证设计出来的日历是呈现一种整齐的效果。

for语句与if语句判断输出

由于我们日历第一列为星期一,但是有的月数第一天不是星期一,而是星期二,这时候我们需要通过for与if语句进行判断,之后输出一个空单元格使之向后面移一位或者几位,达到日与星期对齐的效果,并且星期日在date(‘w’)中为0,还需要通过if去判断是否为星期天

1
2
3
4
5
6
7
8
9
10
if($firstDay==0){ //判断是否为星期天
$r = 7;
$firstDay= $r; //当天数为0时$r为7,则$r给$fristDay赋值为7
for ($i=1; $i < $firstDay ; $i++) { //使用循环结构控制当前月第一天前面的空单元格个数
echo "<td></td>";//输出开始的空单元格,表格中的内容单元格<td>
}else{
for ($i=1; $i < $firstDay ; $i++) { //使用循环结构控制当前月第一天前面的空单元格个数
echo "<td></td>";//输出开始的空单元格,表格中的内容单元格<td>
}
}

之后我们需要知道整个月的时间,就对$day进行遍历

1
2
for ($i=1; $i <= $days ; $i++) {
}

到星期日之后我们还需要让他换行

1
2
3
if (($i + $firstDay -2 ) % 7 == 0) { //判断星期几对应月的天数,如果有空则输出空格
echo "</tr><tr>";
}

这时候我们还需要明确知道今天为几日,我们需要通过设置一个css样式表改变表格中某个单元格的格式,也就是“高亮效果”

1
2
3
<style>
.tdBorder{border: 1px solid #f00;} /* 定义红色边框样式,为突出显示当前日期做准备*/
</style>

最后关键的一步,判断是否为今天,是今天则使用CSS样式表,不是就不使用CSS样式表

1
2
3
4
5
6
if ($i == date('j')) { //判断是否为当天,是当天的话则输出单元格使用的是红色的边框
echo "<td align = 'center' height = '30' class = 'tdBorder'>" . $i . "</td>";
}
else{ //否则不增加边框
echo "<td align = 'center' height = '30' >" . $i . "</td>";
}

最后输出结束的标记和表格结束的标记

1
echo "</tr></table>";

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<style>
.tdBorder{border: 1px solid #f00;} /* 定义红色边框样式,为突出显示当前日期做准备*/
</style>
<?php
$year = date('Y');
$month = date('n');
$date = "$year-$month-1"; //获取当前月第一天的日期格式,如“2018-5-1”。
$str = strtotime($date); //获取指定年份月份第一天的时间戳
$firstDay = date('w',$str); //获取指定时间戳对应的星期几的数字值
//下面获取当前月份的天数
switch ($month) {
case 2 : $days = ($year % 400 == 0 || ($year % 4 ==0 && $year % 100 !=0))? 29 : 28 ; break ; //计算当年二月是否为闰年,是就为29天
case 4 :
case 6 :
case 9 :
case 11 : $days = 30 ; break ;
default: $days = 31; //除了4、6、9、11月其他月份为31天
}
echo "<table width = '366' border = '0' cellpading = '0' cellspacing = '2' align='center'>"; //输出表格,宽度设置为366
echo "<caption>下面是$year$month 月的日历</caption>"; //以表格标题行所在的行标记
echo "<tr align='center'>";
echo "<th width = '50' height = '40'> 一</th> <th width = '50'>二</th>";
echo "<th width = '50' > 三 </th> <th width = '50'>四</th>";
echo "<th width = '50'> 五 </th> <th width = '50'>六</th>";
echo "<th width = '50' > 日 </th> "; //输出标题行单元格及内容
echo "</th><tr>"; //输出标题行结束标记和第一个内容行开始的标
if($firstDay==0){ //判断是否为星期天
$r = 7;
$firstDay= $r; //当天数为0时$r为7,则$r给$fristDay赋值为7
for ($i=1; $i < $firstDay ; $i++) { //使用循环结构控制当前月第一天前面的空单元格个数
echo "<td></td>";//输出开始的空单元格,表格中的内容单元格<td>
}
}else{
for ($i=1; $i < $firstDay ; $i++) { //使用循环结构控制当前月第一天前面的空单元格个数
echo "<td></td>";//输出开始的空单元格,表格中的内容单元格<td>
}
}
for ($i=1; $i <= $days ; $i++) {
if (($i + $firstDay -2 ) % 7 == 0) { //判断星期几对应月的天数,如果有空则输出空格
echo "</tr><tr>";
}
if ($i == date('j')) { //判断是否为当天,是当天的话则输出单元格使用的是红色的边框
echo "<td align = 'center' height = '30' class = 'tdBorder'>" . $i . "</td>";
}
else{ //否则不增加边框
echo "<td align = 'center' height = '30' >" . $i . "</td>";
}
}
echo "</tr></table>"; //输出最后一行结束的标记和表格结束的标记

第二个问题:显示一年所有日历

使用for循环进行遍历

这个问题可以通过for循环来完成,首先在原有的代码上进行循环也就是

1
2
for ($n=1; $n <=12 ; $n++) {//循环遍历一年中12个月的日历
}

之后改变$month

1
$month = $n;  //通过for循环中的数值赋值给$month

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<style>
.tdBorder{border: 1px solid #f00;} /*定义红色边框样式,为突出显示当前日期做准备*/
</style>

<?php
for ($n=1; $n <=12 ; $n++) { //循环遍历一年中12个月的日历
$year = date('Y');
$month = $n; //通过for循环中的数值赋值给$month
$date = "$year-$month-1"; //获取当前月第一天的日期格式,如“2018-5-1”。
$str = strtotime($date); //获取指定年份月份第一天的时间戳
$firstDay = date('w',$str); //获取指定时间戳对应的星期几的数字值
//下面获取当前月份的天数
switch ($n) {
case 2 : $days = ($year % 400 == 0 || ($year % 4 ==0 && $year % 100 !=0))? 29 : 28 ; break ; //计算当年二月是否为闰年,是就为29天
case 4 :
case 6 :
case 9 :
case 11 : $days = 30 ; break ; //4、6、9、11月为30天
default: $days = 31; //除了4、6、9、11月其他月份为31天
}
echo "<table width = '366' border = '0' cellpading = '0' cellspacing = '2' align='center'>"; //输出表格,宽度设置为366
echo "<caption>下面是$year$month 月的日历</caption>"; //以表格标题行所在的行标记
echo "<tr align='center'>";
echo "<th width = '50' height = '40'> 一</th> <th width = '50'>二</th>";
echo "<th width = '50' > 三 </th> <th width = '50'>四</th>";
echo "<th width = '50'> 五 </th> <th width = '50'>六</th>";
echo "<th width = '50' > 日 </th> "; //输出标题行单元格及内容
echo "</th><tr>"; //输出标题行结束标记和第一个内容行开始的标记

if($firstDay==0){ //判断是否为星期天
$r = 7;
$firstDay= $r; //当天数为0时$r为7,则$r给$fristDay赋值为7
for ($i=1; $i < $firstDay ; $i++) { //使用循环结构控制当前月第一天前面的空单元格个数
echo "<td></td>";//输出开始的空单元格,表格中的内容单元格<td>
}
}else{
for ($i=1; $i < $firstDay ; $i++) { //使用循环结构控制当前月第一天前面的空单元格个数
echo "<td></td>";//输出开始的空单元格,表格中的内容单元格<td>
}
}
for ($i=1; $i <= $days ; $i++) {
if (($i + $firstDay -2 ) % 7 == 0) { //判断星期几对应月的天数,如果有空则输出空格
echo "</tr><tr>";
}
if ($i == date('j') && $n == date('n')) { //判断是否为当天,是当天的话则输出单元格使用的是红色的边框
echo "<td align = 'center' height = '30' class = 'tdBorder'>" . $i . "</td>";
}
else{ //否则不增加边框
echo "<td align = 'center' height = '30' >" . $i . "</td>";
}
}
echo "</tr></table>"; //输出最后一行结束的标记和表格结束的标记
}

?>

第三个问题:改变日历年份

我们以下一年为例,将$year进行改变

1
$year = date('Y',strtotime("+1 year"));

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<style>
.tdBorder{border: 1px solid #f00;} /*定义红色边框样式,为突出显示当前日期做准备*/
</style>

<?php
for ($n=1; $n <=12 ; $n++) { //循环遍历一年中12个月的日历
$year = date('Y',strtotime("+1 year"));//通过修改变量year时间戳达到下一年的效果
$month = $n; //通过for循环中的数值赋值给$month
$date = "$year-$month-1"; //获取当前月第一天的日期格式,如“2018-5-1”。
$str = strtotime($date); //获取指定年份月份第一天的时间戳
$firstDay = date('w',$str); //获取指定时间戳对应的星期几的数字值
//下面获取当前月份的天数
switch ($n) {
case 2 : $days = ($year % 400 == 0 || ($year % 4 ==0 && $year % 100 !=0))? 29 : 28 ; break ; //计算当年二月是否为闰年,是就为29天
case 4 :
case 6 :
case 9 :
case 11 : $days = 30 ; break ; //4、6、9、11月为30天
default: $days = 31; //除了4、6、9、11月其他月份为31天
}
echo "<table width = '366' border = '0' cellpading = '0' cellspacing = '2' align='center'>"; //输出表格,宽度设置为366
echo "<caption>下面是$year$month 月的日历</caption>"; //以表格标题行所在的行标记
echo "<tr align='center'>";
echo "<th width = '50' height = '40'> 一</th> <th width = '50'>二</th>";
echo "<th width = '50' > 三 </th> <th width = '50'>四</th>";
echo "<th width = '50'> 五 </th> <th width = '50'>六</th>";
echo "<th width = '50' > 日 </th> "; //输出标题行单元格及内容
echo "</th><tr>"; //输出标题行结束标记和第一个内容行开始的标记

if($firstDay==0){ //判断是否为星期天
$r = 7;
$firstDay= $r; //当天数为0时$r为7,则$r给$fristDay赋值为7
for ($i=1; $i < $firstDay ; $i++) { //使用循环结构控制当前月第一天前面的空单元格个数
echo "<td></td>";//输出开始的空单元格,表格中的内容单元格<td>
}
}else{
for ($i=1; $i < $firstDay ; $i++) { //使用循环结构控制当前月第一天前面的空单元格个数
echo "<td></td>";//输出开始的空单元格,表格中的内容单元格<td>
}
}
for ($i=1; $i <= $days ; $i++) {
if (($i + $firstDay -2 ) % 7 == 0) { //判断星期几对应月的天数,如果有空则输出空格
echo "</tr><tr>";
}
if ($i == date('j') && $n == date('n')) { //判断是否为当天,是当天的话则输出单元格使用的是红色的边框
echo "<td align = 'center' height = '30' class = 'tdBorder'>" . $i . "</td>";
}
else{ //否则不增加边框
echo "<td align = 'center' height = '30' >" . $i . "</td>";
}
}
echo "</tr></table>"; //输出最后一行结束的标记和表格结束的标记
}

?>

总结

该题目并不是很难,只要熟练掌握php基础语法基本上可以写出这种题,需要注意的也就日历框架的构建,以及各种逻辑思维的判断(例:星期日在date(‘w’)中为0,需要对星期日重新判断等)和时间戳的使用。