cookieを使ったカレンダーの作り方 - PHPプロ!Q&A掲示板

3011

  • 0P

cookieを使ったカレンダーの作り方

質問日時 / 2010年12月12日 01:11    回答数 / 4件

Questioner:  keitaroh0604  このエントリーをはてなブックマークに追加 

キーワード / クッキー    セッション   

 先日、「チェックボックス付カレンダーの作成について
教えてください。」と書き込みしたものです。
 先日とほとんど同じ内容の質問かもしれないので
もしルールに反した書き込みに該当するようでしたら
申し訳ありません。
 下記のコードでチェックボックス付カレンダーをつくりました。

 やりたいこと
 2010年12月21日にチェックをつけて、
画面の『翌月』をクリックして2011年1月5日に
チェックをつけて「確定」ボタンをおしたら
post_calender3.phpに2010年12月21日と
2011年1月5日が表示されるようにしたいです。

 coockieを使うと良いらしいことは
教えていただいたのですが、マニュアルを見ても
今回の場合どのようにcoockieを使ったコードを
書けばよいのか、分かりません。

 本当に恐縮ですがどのようにすればよいのか
教えていただけませんでしょうか?
よろしくお願いいたします。
ちなみにクッキーにこだわっているわけではないので
セッションなんかでできる方法あったら教えてください。



  1. calender.php
  2. <html>
  3. <body>
  4. <form action="post_calender3.php" method="post">
  5. <?php
  6.  
  7. //年月日取得
  8. $year = date("Y");
  9. $month = date("n");
  10. $day = date("j");
  11.  
  12. //先月、来月をクリックした時の処理
  13. if (is_null(@$_GET["year"])){
  14.      $year = date("Y");
  15.      $month = date("n");
  16.      $day = date("j");
  17.  }else{
  18.  
  19.      $year =@$_GET["year"];
  20.      $month =@$_GET["month"];
  21.      $mktime = mktime(0,0,0,$month,1,$year);
  22. }
  23.  
  24. //カレンダーを表示する
  25. //先月の場合
  26. if($month==1){
  27.   $pre_year = $year-1;
  28.   $pre_month = 12;
  29. }
  30. else{
  31.   $pre_year = $year;
  32.   $pre_month = $month-1;
  33. }
  34.  
  35. //来月の場合
  36. if($month==12){
  37.   $next_year = $year+1;
  38.   $next_month = 1;
  39. }
  40. else{
  41.   $next_year = $year;
  42.   $next_month = $month+1;
  43. }  
  44.  
  45. //月の日数取得
  46. $countdate = date("t",$mktime);
  47.  
  48. //曜日の配列を作る
  49. $weekday = array("","","","","","","");
  50.  
  51. print "<a href=?year=$pre_year&month=$pre_month>".先月."</a>";
  52. print "<caption>".$year."".$month."月</caption>";
  53. print "<a href=?year=$next_year&month=$next_month>".翌月."</a>";
  54. print '<table border="1">';
  55.  
  56. //曜日セルタグ設定
  57. $i = 0;
  58. while ($i<=6){
  59. print "<th>".$weekday[$i]."</th>";
  60. $i++;
  61. }
  62.  
  63. //行の変更
  64. print "</tr>";
  65. print "<tr>";
  66.  
  67. //1日(ついたち)の曜日を数値で取得
  68. $first_weekday = date("w",mktime(0,0,0,$month,1,$year));
  69.  
  70. //1日(ついたち)の曜日まで空白埋め
  71. $i =0;
  72. while($i$first_weekday){
  73. print "<td>&nbsp;</td>";
  74. $i++;
  75. }
  76.  
  77. //今月の日付が存在している間ループする
  78. for ($day = 1$day <= $countdate$i++,$day++){
  79.   //土曜日まできたらカウント値($i)を0に戻して行を変更
  80.   if($i>6){
  81.     $i=0;
  82.     print "</tr>";
  83.     print "<tr>";
  84.   }
  85.  print "<td>".$day."<input type='checkbox' name='day[]'value=$day>"."</td>";
  86.  
  87. }
  88. print '</table>';
  89. ?>
  90.  
  91. <br>
  92. <input type="submit" value="確定">
  93. </form>
  94. </body>
  95. </html>
  96.  
  97. post_calender3.php
  98. <?php
  99.  
  100. foreach ($_POST["day"] as $day){
  101. print $day."<br>";
  102. }
  103.  
  104. ?>

この質問への意見の募集は締め切られ、ポイントは既に配分されました。
意見を投稿することはできますが、ポイントを受け取ることはできません。



ツリー一覧

┗A01shimix前回(http://www.phppro.jp/qa/3011)のレスで「Java
 ┗A01-1keitaroh0604shimix様 いつも本当にありがとうございます。 前
  ┗A01-1-1shimix#蛇足ですが(汗 COOKIEを使う場合でも、基本的に
   ┗A01-1-1-1keitaroh0604shimix様 またまた丁寧な解説、本当にありがとうご

回答一覧

並び替え:

A01 満足
answerershimix [12月13日 14:25]

前回(http://www.phppro.jp/qa/3011)のレスで「JavaScriptに頼らずに、サーバで処理するなら[前月][翌月]の遷移もsubmitにする必要がある」と書きましたが、それは考慮されなかったのでしょうか?

一応、hiddenで持ち回るタイプとしてざくっと書いてみました。細かいセキュリティ対策とか冗長になってしまった部分の集約などはまだまだですが『どういう動きをさせればいいか』だけは読み取れるんじゃないかと思います。


  1. <?php
  2. $array = array();
  3. //年月日(初期値)取得
  4. $yymm = date('Y/m');
  5. $day = date('d');
  6. $wdate = strtotime($yymm . '/' . $day);
  7. if ($_POST) {
  8.     //前のフォームで処理していた年月日
  9.     $yymm = $_POST['yymm'];
  10.     // 今月?
  11.     if ($yymm == date('Y/m')) {
  12.         $day = date('d');
  13.     } else {
  14.         $day = '01';
  15.     }
  16.     $wdate = strtotime($yymm . '/' . $day);
  17.     // hiddenで持ち回っていたデータ
  18.     if (is_array($_POST[svdata])) {
  19.         foreach($_POST[svdata] as $val) { $array[] = $val}
  20.     }
  21.     // 前のフォームの年月のデータ
  22.     for ($i = 1$i <= date('t'strtotime($yymm . '/01'))$i++){
  23.         $s = sprintf('%02d'$i);
  24.         if ($_POST['day']) {
  25.             if (in_array($s$_POST['day'])) {
  26.                 $array[] = $yymm . '/' . $s;
  27.             }
  28.         }
  29.     }
  30.     if ($_POST['submit']) {
  31.         var_dump($array)// 本番では処理ロジックをincludeする
  32.         exit;
  33.     }
  34.  
  35.     // 今から表示するフォームの年月(前月・翌月のsubmitを反映)
  36.     if ($_POST['prev']) { $wdate = strtotime('first day -1 month'$wdate)}
  37.     if ($_POST['next']) { $wdate = strtotime('first day +1 month'$wdate)}
  38.     $yymm = date('Y/m'$wdate);
  39. }
  40. //月の日数取得
  41. $countdate = date('t',$wdate);
  42. //曜日の配列を作る
  43. $weekday = array("","","","","","","");
  44. ?>
  45. <html>
  46. <body>
  47. <form action="" method="post">
  48. <input type="submit" name="prev" value="先月" >
  49. <caption><?php echo date('Y / m'$wdate)?></caption>
  50. <input type="hidden" name="yymm" value="<?php echo date('Y/m'$wdate)?>">
  51. <input type="submit" name="next" value="翌月" >
  52. <?php
  53. // 今月以外をhiddenで埋め込む
  54. foreach ($array as $val) {
  55.     if (substr($val,0,7) == date('Y/m'$wdate)) { continue}
  56.     print '<input type="hidden" name="svdata[]" value="' . $val . '">';
  57. }
  58. ?>
  59. <table border="1">
  60. <tr>
  61. <?php
  62. //曜日セルタグ設定
  63. $i = 0;
  64. while ($i<=6) {
  65.     print "<th>".$weekday[$i]."</th>";
  66.     $i++;
  67. }
  68. ?>
  69. </tr>
  70. <tr>
  71. <?php
  72. //1日(ついたち)の曜日を数値で取得
  73. $first_weekday = date("w"strtotime('first day'$wdate));
  74.  
  75. //1日(ついたち)の曜日まで空白埋め
  76. $i =0;
  77. while($i$first_weekday) {
  78.     print "<td>&nbsp;</td>";
  79.     $i++;
  80. }
  81. //今月の日付が存在している間ループする
  82. for ($day = 1$day <= $countdate$i++,$day++) {
  83.     //土曜日まできたらカウント値($i)を0に戻して行を変更
  84.     if($i>6){
  85.         $i=0;
  86.         print '</tr>' . PHP_EOL . '<tr>';
  87.     }
  88.     $s = sprintf('%02d',$day);
  89.     if (in_array(date('Y/m/',$wdate) . $s$array)) {
  90.         print '<td>' . $day . '<input type="checkbox" ';
  91.         print 'name="day[]" value="' . $s . '" checked>';
  92.     } else {
  93.         print '<td>' . $day . '<input type="checkbox" ';
  94.         print 'name="day[]" value="' . $s . '">';
  95.     }
  96.     print "</td>";
  97. }
  98. print '</table>';
  99. ?>
  100.  
  101. <br>
  102. <input type="submit" name="submit" value="確定">
  103. </form>
  104. </body>
  105. </html>

この意見に回答する

ツリーへ TOPへ

A01-1
replyerkeitaroh0604 [12月14日 02:25]

shimix様
いつも本当にありがとうございます。

前回「JavaScriptに頼らずに、サーバで処理するなら[前月][翌月]の遷移もsubmitにする必要がある」と教えていただいたのですが、私の知識不足で「サーバーで処理する」の意味が
調べても分からず、クッキーを使っての方法を検討していました。

hiddenで持ち回るタイプのコードをわざわざ書いていただいてありがとうございます。
書いていただいた内容を勉強させていただきます。

この意見に回答する

ツリーへ TOPへ

A01-1-1 満足
replyershimix [12月14日 11:21] (最終編集:12月15日 14:09)

#蛇足ですが(汗

COOKIEを使う場合でも、基本的にはフォームのhiddenと考え方は変りません。読み書きのタイミングが変るくらいですね。

  1. <?php
  2. $array = array();
  3. if ($_COOKIE['ymd']) { $array = unserialize($_COOKIE['ymd'])}
  4.  
  5. //年月日(初期値)取得
  6. $yymm = date('Y/m');
  7. $day = date('d');
  8. $wdate = strtotime($yymm . '/' . $day);
  9. if ($_POST) {
  10.     //前のフォームで処理していた年月日
  11.     $yymm = $_POST['yymm'];
  12.     // 今月?
  13.     if ($yymm == date('Y/m')) {
  14.         $day = date('d');
  15.     } else {
  16.         $day = '01';
  17.     }
  18.     $wdate = strtotime($yymm . '/' . $day);
  19.     // 前のフォームの年月のデータ
  20.     for ($i = 1$i <= date('t'strtotime($yymm . '/01'))$i++){
  21.         $s = sprintf('%02d'$i);
  22.         if ($_POST['day']) {
  23.             if (in_array($s$_POST['day'])) {
  24.                 $array[] = $yymm . '/' . $s;
  25.             }
  26.         }
  27.     }
  28.     if ($_POST['submit']) {
  29.         var_dump($array)// 本番では処理ロジックをincludeする
  30.         exit;
  31.     }
  32.  
  33.     // 今から表示するフォームの年月(前月・翌月のsubmitを反映)
  34.     if ($_POST['prev']) { $wdate = strtotime('first day -1 month'$wdate)}
  35.     if ($_POST['next']) { $wdate = strtotime('first day +1 month'$wdate)}
  36.     $yymm = date('Y/m'$wdate);
  37. }
  38. // 今月以外をcookieへ
  39. $cookie = array();
  40. foreach ($array as $val) {
  41.     if (substr($val,0,7) == date('Y/m'$wdate)) { continue}
  42.     $cookie[] = $val;
  43. }
  44. setcookie('ymd'serialize($cookie));
  45. //月の日数取得
  46. $countdate = date('t',$wdate);
  47. //曜日の配列を作る
  48. $weekday = array("","","","","","","");
  49. ?>
  50. <html>
  51. <body>
  52. <form action="" method="post">
  53. <input type="submit" name="prev" value="先月" >
  54. <caption><?php echo date('Y / m'$wdate)?></caption>
  55. <input type="hidden" name="yymm" value="<?php echo date('Y/m'$wdate)?>">
  56. <input type="submit" name="next" value="翌月" >
  57. <table border="1">
  58. <tr>
  59. <?php
  60. //曜日セルタグ設定
  61. $i = 0;
  62. while ($i<=6) {
  63.     print "<th>".$weekday[$i]."</th>";
  64.     $i++;
  65. }
  66. ?>
  67. </tr>
  68. <tr>
  69. <?php
  70. //1日(ついたち)の曜日を数値で取得
  71. $first_weekday = date("w"strtotime('first day'$wdate));
  72.  
  73. //1日(ついたち)の曜日まで空白埋め
  74. $i =0;
  75. while($i$first_weekday) {
  76.     print "<td>&nbsp;</td>";
  77.     $i++;
  78. }
  79. //今月の日付が存在している間ループする
  80. for ($day = 1$day <= $countdate$i++,$day++) {
  81.     //土曜日まできたらカウント値($i)を0に戻して行を変更
  82.     if($i>6){
  83.         $i=0;
  84.         print '</tr>' . PHP_EOL . '<tr>';
  85.     }
  86.     $s = sprintf('%02d',$day);
  87.     if (in_array(date('Y/m/',$wdate) . $s$array)) {
  88.         print '<td>' . $day . '<input type="checkbox" ';
  89.         print 'name="day[]" value="' . $s . '" checked>';
  90.     } else {
  91.         print '<td>' . $day . '<input type="checkbox" ';
  92.         print 'name="day[]" value="' . $s . '">';
  93.     }
  94.     print "</td>";
  95. }
  96. print '</table>';
  97. ?>
  98.  
  99. <br>
  100. <input type="submit" name="submit" value="確定">
  101. </form>
  102. </body>
  103. </html>
  104. <?php
  105. // デバッグ用
  106. print '<hr>' . PHP_EOL;
  107. var_dump($_POST);
  108. ?>


追記(さらに蛇足ですが)。

重要なのは・・

今から表示するフォーム(年月)に含まれる年月日のデータはhiddenやcookieを使わないということですね。チェックをOffにする可能性がありますから。当該年月の既存データはチェックボックスをcheckedにすることで代用します。

それとcookieを使う場合はserialize/unserializeで配列をまとめて渡すことですね。cookieには個数制限がありますし(最大個数はブラウザ依存です)、年月日で個別にcookieを作ってしまうとチェックボックスをOffにしたときに削除しないといけなくなります。

この意見に回答する

ツリーへ TOPへ

A01-1-1-1
replyerkeitaroh0604 [12月15日 23:14]

shimix様

またまた丁寧な解説、本当にありがとうございます。
恥ずかしながらせっかく教えていただいたのに
私の知識がまだ追いついておりません。
教えていただいた内容が無駄にならないよう
一生懸命勉強させていただきます。

この意見に回答する

ツリーへ TOPへ

<<質問一覧へ



Pick Up Q&A

Q
マジッククォートとmysql_real_escape_string
 このエントリーをはてなブックマークに追加 
A
magic_quotes_gpcでは、SQLインジェクション対処は十分できません。主な理由として、以下が上げられます。 ・magic_quotes_gpcは文字コードを考慮しないで処理するので、Shift_JISを使っている場合、SQLインジェ...

>>続きを読む

SQLインジェクション対策は時と場合で使う関数が変わります。その時にあったものを使いましょう。

▲解説者:岡本(アシアル株式会社 教育コーディネーター兼 システムエンジニア)