PHP经典实例(php cookbook)读书笔记(0x03.E6)
目录
程序:日历
<style type="text/css">
.prev{text-align:left;}
.next{text-align:right;}
.day,.month,.weekday{text-align:center;}
.today{background:yellow;}
.blank{}
</style>
程序简要流程
LittleCalendar类属性
protected $monthToUse;//一个DateTime对象
protected $prepared = false;//初始化开关
protected $days =array();//一个日期格子的属性
构造函数
public function __construct($month,$year){
$this->monthToUse = DateTime::createFromFormat('Y-m' , sprintf("%04d-%02d",$year,$month));//此处有个BUG就是createFromeFormat如果不输入日期就会默认为当前日期,那么在日期处理起点会从今天开始,这样你会发现打印的时候第一个日期总是今天,所以这里应该改成$this->monthToUse = DateTime::createFromFormat('Y-m-d' ,sprintf("%04d-%02d-01",$year,$month));
$this->prepare();
}
prepare函数主要是设置要显示的表格的信息
protected function prepare(){
//先设置第一行格子显示星期日-六的表格头
foreach(array('Su','Mo','Tu','We','Th','Fr','Sa') as $dow){
$endOfRow = ($dow == 'Sa');
$this->days[]=array('type' => 'dow',
'label' => $dow,
'endOfRow' => $endOfRow);
}
//将一个月的前几天填充(因为1号不一定是星期1,需要将前几格填充)
for($i=0,$j = $this->monthToUse->format('w');$i<$j;$i++)//format('w')取一周中的第几天星期天为0
$this->days[] = array('type' => 'blank');
//然后,处理每个格子的日期
$today=date('Y-m-d');
$days = new DatePeriod(//获得一个时间段的日期
$this->monthToUse,//开始时间
new DateInterval('P1D'),//间隔一天
$this->monthToUse->format('t') - 1//结束日期
);
foreach($days as $day){
$isToday = ($day->format('Y-m-d') == $today);
$endOfRow = ($day->format('w') == 6);
$this->days[] = array('type' => 'day',
'label' => $day->format('j'),
'today' => $isToday,
'endOfRow' => $endOfRow);
}
//与开始一样,将月末的空余填满
if(! $endOfRow){
for($i=0,$j=6-$this->monthToUse->format('w')format('w');$i < $j;$i++){
$this->days[] = array('type' => 'blank');
}
}
}
html渲染函数
public function html(){
if(! isset($pots['id'])){
$opts['id']='日历';
}
if(! isset($opts['month_link'])){
$opts['month_link']='<a href="'.htmlentities($_SERVER['PHP_SELF']).'?'.'month=%d&year=%d">%s</a>';
}
$classes=array();
foreach(array('prev','month','next','weekday','blank','day','today') as $class){
if(isset($opts['class']) && isset($opts['class'][$class])){
$classes[$class] = $opts['class'][$class];
}
else{
$classes[$class] = $class;
}
}
$prevMonth = clone $this->monthToUse;
$prevMonth->modify("-1 month");
$prevMonthLink = sprintf($opts['month_link'],
$prevMonth->format('m'),
$prevMonth->format('Y'),
'«');
$nextMonth = clone $this->monthToUse;
$nextMonth->modify("-1 month");
$nextMonthLink = sprintf($opts['month_link'],
$nextMonth->format('m'),
$nextMonth->format('Y'),
'»');
$html = '<table id="'.htmlentities($opts['id']).'">
<tr>
<td class="'.htmlentities($classes['prev']).'">'.
$prevMonthLink.'</td>
<td class = "'.htmlentities($classes['month']).'" colspan="5">'.
$this->monthToUse->format('F Y').'</td>
<td class ="'.htmlentities($classes['next']).'">'.
$nextMonthLink . '</td>
</tr>';
$html.='<tr>';
$lastDayIndex = count($this->days) - 1;
foreach($this ->days as $i => $day){
switch($day['type']){
case 'dow':
$class = 'weekday';
$label = htmlentities($day['label']);
break;
case 'blank':
$class = 'blank';
$label = ' ';
break;
case 'day';
$class = $day['today']? 'today':'day';
$label = htmlentities($day ['label']);
break;
}
$html .=
'<td class ="' .htmlentities($classes[$class]).'">'.
$label . '</td>';
if(isset($day['endOfRow']) && $day['endOfRow']){
$html .= "</tr>\n";
if($i !=$lastDayIndex){
$html .= '<tr>';
}
}
}
$html .= '</table>';
return $html;
结果展示: