カレンダーを関数化・・・

カレンダー4で作成したプログラムを関数化しようと思います。

関数化するプログラミングは、構造化プログラミングというプログラミング技法でオブジェクト指向が登場するまで主流だった技法です。
プログラミングを関数化していくことで、再利用、部品化することでソースを簡略化していく事ができます。

関数は、関数定義と呼び出しの2つの記述が必要となります。
関数定義とは、関数の処理内容を記述です。具体的なソースでいうと

function MyFunc(){
echo ”  MyFunc is calling.\n”;
}

が、関数定義です。
上記の関数定義を呼び出すソースは下記のようになる。

echo “Main Program\n\n”;
MyFunc();
exit();

上記のような、関数定義と呼び出しを使って、カレンダー4のプログラムを関数化すると下記のようなソースになる。

 

//月カレンダーの作成
//関数化
$smarty = new MySmarty();

$week = array(
‘日’,
‘月’,
‘火’,
‘水’,
‘木’,
‘金’,
‘土’,
);
$smarty->assign( ‘week’, $week );

$disp_date = ”;
//表示日付のセット
if( isset($_REQUEST[‘disp_date’]) && strlen($_REQUEST[‘disp_date’]) ){
$disp_date = $_REQUEST[‘disp_date’];
}

$calendar = makeCalendar( $disp_date );
//デフォルトは今日を表示
$smarty->assign( ‘year’, $calendar[‘today’][‘year’] );
$smarty->assign( ‘month’, $calendar[‘today’][‘month’] );
$smarty->assign( ‘day’, $calendar[‘today’][‘day’] );

//前月リンク
$smarty->assign( ‘prev_month’, $calendar[‘prev_month’] );

//翌月リンク
$smarty->assign( ‘next_month’, $calendar[‘next_month’] );

$smarty->assign( ‘disp_year’, $calendar[‘disp_month’][‘year’] );
$smarty->assign( ‘disp_month’, $calendar[‘disp_month’][‘month’] );
$smarty->assign( ‘disp_day’, $calendar[‘disp_month’][‘day’] );

$smarty->assign( ‘month_date’, $calendar[‘disp_month’][‘dates’] );

$smarty->display( ‘smarty01/lesson05.tpl’);
exit;

//========================================================================================

function makeCalendar( $disp_date = ” ){
$ret = array();

$now = time();

$year = date(‘Y’, $now);
$month= date(‘m’, $now);
$day= date(‘d’, $now);

$ret[‘today’][‘year’] = $year;
$ret[‘today’][‘month’] = $month;
$ret[‘today’][‘day’] = $day;
$ret[‘today’][‘disp’] = “{$year}/{$month}/{$day}”;

//表示日付のセット
if( strlen($disp_date) ){
$tmp = explode( ‘/’, $_REQUEST[‘disp_date’] );
$year = $tmp[0];
$month = $tmp[1];
$day = $tmp[2];
}
//表示付きの情報
$ret[‘disp_month’][‘year’] = $year;
$ret[‘disp_month’][‘month’]= $month;
$ret[‘disp_month’][‘day’]= 1;

//前月リンク
$prev_year = $year;
$prev_month = $month – 1;
if( $prev_month <= 0 ) {
$prev_month = 12;
$prev_year –;
}
$ret[‘prev_month’] = “{$prev_year}/{$prev_month}/1”;

//翌月リンク
$next_year = $year;
$next_month = $month + 1;
if( $next_month > 12 ){
$next_month -= 12;
$next_year ++;
}
$ret[‘next_month’] = “{$next_year}/{$next_month}/1”;

//月の始めの時間取得
$month_startDate = strtotime( “{$year}/{$month}/1” );
//表示付きの表示テキスト
$ret[‘disp_month’][‘disp’] = $month_startDate;
$ret[‘disp_month’][‘dispMonth’] = “{$year}年{$month}月”;

//月はじめの曜日を取得
$month_startWeek = date( ‘w’, $month_startDate );
$ret[‘disp_month’][‘week’]= $month_startWeek;

//今月の日数の取得
$month_dates = date(‘t’, strtotime($month_startDate) );

//月の週配列を作成
$month_date = array();

//月初めの週の空いている枠を埋める
for( $n = 0; $n < 7; $n ++ ){
$month_date[0][$n] = ‘&nbsp;’;
}

$weekOffset = date( ‘W’, $month_startDate );
for( $n = 1; $n <= $month_dates; $n ++ ){
$date = strtotime( “{$year}/{$month}/{$n}” );

$nWeek = date(‘W’, $date) – $weekOffset;

$w = date(‘w’, $date );
if( $w == 0 ) $nWeek ++;

//年末が月曜日移行の時、date(‘W’)の返り値が1となるので
//計算を補正する
//date関数の不具合かもしれない
if( $nWeek < 0 ){
$tmpDate = $date – ( $w * 24 * 3600 );
$nWeek = date(‘W’, $tmpDate ) – $weekOffset;
if( date(‘w’, $tmpDate ) == 0 ) $nWeek ++;
}

$month_date[$nWeek][$w] = $n;
}
//月終わりの空いている枠を埋める
$month_endDate = strtotime( “{$year}/{$month}/{$month_dates}” );
$month_endWeek = date(‘w’, $month_endDate );
if( $month_endWeek < 6 ){
$w = date(‘W’, $month_endDate) – $weekOffset;

//年末が月曜日移行の時、date(‘W’)の返り値が1となるので
//計算を補正する
if( $w < 0 ){
$tmpDate = $month_endDate – ($month_endWeek * 24 * 3600 );
$w = date( ‘W’, $tmpDate );
if( date(‘w’, $tmpDate) == 0 ){
$w ++;
}
$w -= $weekOffset;
}

for( $n = $month_endWeek+1; $n < 7; $n ++ ){
$month_date[$w][$n] = ‘&nbsp;’;
}
}

$ret[‘disp_month’][‘dates’] = $month_date;

return $ret;
}

テンプレートファイルは、同じものを使用できます。
上記のソースでは、lesson05.tplとしているが、内容はlesson04.tplと同等の内容です。なので省略します。

結果はこちら