忍者ブログ
[PR]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。



2024/11/22 15:28 |
PHP1-32:PHPでカレンダー

Pear::Calendar 0.5.3 (beta)
http://pear.php.net/package/Calendar/

たとえばこのブログでは右側に表示されているカレンダー、そういうのを簡単に作成することの出来るパッケージです。
ブログの場合は日付毎の記事等と連動しているので最初からブログシステムに組み込まれている場合がほとんどで、特に自作する必要はありません。
しかし自力で実装を行おうと思った場合はそれなりに面倒です。
そんな場合にPear::Calenderが便利だよ、ということなのですが、これがまたはっきりいってものすごく使いづらい。
クラスやファイルが多くてインクルードが面倒だったり、どのファイルのどのクラスがどの機能を持っているのかが分かり難かったり、取得したところで結局自分でタグ書かないといけなかったり。
$calender->getMonthTable('2008','9')みたいなことができず、Calendar_Month_Weekdaysオブジェクトをbuildして、isFirst、isLastでチェックしつつfetchしなけりゃいけないので自作するのとあまり手間が変わらなかったりします。
さらに何故かCalendarクラスの初期値が'2001-01-01 00:00:00'とかになっているので(普通nowだろ)どうにかします。

というわけでテーブル作成部分などを例によってラッパークラスに押し込みます。
汎用性?窓から投げ捨てろ。
フツーにstrtotimeやらgetdateやら使用しているせいでPear::Date涙目なのですがそれもまた気にしない。

calender.class.php

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
<?php
    //初期設定
    require_once(PEAR_DIR.'Calendar/Calendar.php');
    require_once(PEAR_DIR.'Calendar/Year.php');
    require_once(PEAR_DIR.'Calendar/Month.php');
    require_once(PEAR_DIR.'Calendar/Week.php');
    require_once(PEAR_DIR.'Calendar/Day.php');
    require_once(PEAR_DIR.'Calendar/Hour.php');
    require_once(PEAR_DIR.'Calendar/Minute.php');
    require_once(PEAR_DIR.'Calendar/Second.php');
    require_once(PEAR_DIR.'Calendar/Month/Weekdays.php');
    require_once(PEAR_DIR.'Calendar/Month/Weeks.php');
    require_once(PEAR_DIR.'Calendar/Table/Helper.php');
    
    class pearCalenderModel {
        //メンバ変数
        private $calender = array();
        private $date_array = array();
        private $table='';
        private $firstday=0;
        
        //コンストラクタ
        //引数は$date:'Y-m-d h:i:s(strtotimeが理解できる形式)'
        //$firstday:最初を何曜日にするか0:Sun,1:Mon,…,6:Sat
        public function __construct($date='',$firstday=null){
            $this->setDate($date);
            $this->calender = new Calendar(
                $this->date_array['year'],
                $this->date_array['mon'],
                $this->date_array['mday'],
                $this->date_array['hours'],
                $this->date_array['minutes'],
                $this->date_array['seconds']
            );
            if($firstday!==null){$this->firstday = (int)$firstday;}
        }
    
        //月別カレンダーを作成
        public function createMonthTable(){
            $this->_tableHelper();
            $Month = new Calendar_Month_Weekdays(
                $this->date_array['year'],
                $this->date_array['mon'],
                $this->firstday);
            $Month->build();
            
            $ret= '<table border="1"><tr>';
            $DaysOfWeek=$this->table->getDaysOfWeek();
            foreach($DaysOfWeek as $val){
                switch($val){
                    case 0:$ret.= '<th>Sun</th>';break;
                    case 1:$ret.= '<th>Mon</th>';break;
                    case 2:$ret.= '<th>Tue</th>';break;
                    case 3:$ret.= '<th>Wed</th>';break;
                    case 4:$ret.= '<th>Thu</th>';break;
                    case 5:$ret.= '<th>Fri</th>';break;
                    case 6:$ret.= '<th>Sat</th>';break;
                }
            }
            $ret.='</tr>';
 
            while ($Day = $Month->fetch()) {
                if ($Day->isFirst()) {
                    $ret.= "<tr>";
                }
                if ($Day->isEmpty()) {
                    $ret.= "<td>&nbsp;</td>";
                }else{
                    $ret.= '<td>'.$Day->thisDay()."</td>";
                }
                if($Day->isLast()){
                    $ret.= "</tr>";
                }
            }
            $ret.= "</table>";
            return $ret;
        }
    
        //週間カレンダーを作成
        public function createWeekTable(){
            $this->_tableHelper();
            
            $Week = new Calendar_Week(
                $this->date_array['year'],
                $this->date_array['mon'],
                $this->date_array['mday'],
                $this->firstday);
            $Week->build();
            
            $ret= '<table border="1"><tr>';
            $DaysOfWeek=$this->table->getDaysOfWeek();
            foreach($DaysOfWeek as $val){
                switch($val){
                    case 0:$ret.= '<th>Sun</th>';break;
                    case 1:$ret.= '<th>Mon</th>';break;
                    case 2:$ret.= '<th>Tue</th>';break;
                    case 3:$ret.= '<th>Wed</th>';break;
                    case 4:$ret.= '<th>Thu</th>';break;
                    case 5:$ret.= '<th>Fri</th>';break;
                    case 6:$ret.= '<th>Sat</th>';break;
                }
            }
            $ret.='</tr><tr>';
            while ($Day = $Week->fetch()) {
                $ret.= '<td>'.$Day->thisMonth().'/'.$Day->thisDay()."</td>";
            }
            $ret.= '</tr></table>';
            return $ret;
        }
    
        //日付を設定
        public function setDate($date=''){
            if($date){
                $this->date_array=getdate(strtotime($date));
                if($this->date_array==false){
                    $this->date_array=getdate();
                }
            }else{
                $this->date_array=getdate();
            }
        }
    
        //日付を取得
        public function getDate(){
            return $this->date_array;
        }
        
        //Calendar_Table_Helperインスタンスを作成
        private function _tableHelper(){
            if($this->table){return false;}
            
            $this->table = new Calendar_Table_Helper
                ($this->calender,$this->firstday);
            return true;
        }
    
    #↓クラスのおわり
    }


これだけ書いて実装できたのはcreateMonthTable()およびcreateWeekTable()だけです。
それぞれ任意の日付が含まれる月間カレンダー、週間カレンダーを作成します。
以下のように使用します。

calender.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
    #初期設定
    header("Content-type: text/html; charset=utf-8");
    require_once('./calender.class.php');
    
    $calender = new pearCalenderModel();
    //$calender = new pearCalenderModel('2008-09-25 00:00:00',0);
    
    $cal_now=$calender->getDate();
    $cal_now=$cal_now['year'].''.$cal_now['mon'].'';
    
    $cal_m=$calender->createMonthTable();
    $cal_w=$calender->createWeekTable();
    
    print($cal_now.'<br />'.$cal_m.'<br />'.$cal_w);


new時に引数としてY-m-d h:i:s形式の日付(省略するとnow)、およびカレンダーの曜日を何曜日から始めるかの二つを渡します。
最初はcreate時に$firstdayを与えるつもりだったのですが、Calender::firstdayは中でfirstdayをdefineしてやがる。
カレンダーを作成するたびにクラスをnewするのも馬鹿みたいなので適当に実装しました。
変更するならコンストラクタでやってることを各メソッドに持って行けばいいです。

最初にrequireしているファイルの半分も使っていませんが、だいたいWebで必要なカレンダーなんてこの程度しかないような。
何かほしいものがあるならばおいおい追加していくといいかもしれませんし一から作った方が早いかもしれません。
どうせPHPで行うなら単なるカレンダーではなく、DBと連携して予定表などを取得してみるのもいいかもしれません。
DBなどと連動しない場合はわざわざサーバに負担をかける必要もないので、YUIカレンダー等のJavaScriptベースのカレンダーを使用した方がいいでしょう。

 

PR


2008/10/09 11:18 | Comments(0) | TrackBack() | PHP

トラックバック

トラックバックURL:

コメント

コメントを投稿する






Vodafone絵文字 i-mode絵文字 Ezweb絵文字 (絵文字)



<<PHP1-33:PHPでカプレカその1 | HOME | PHP1-31:PHPでソケット接続>>
忍者ブログ[PR]