PHP カレンダー


カレンダーにはテーブルの中に、phpのdate関数フォーマットを使います。wはNumeric representation of the day of the weekです。
PHP Date:http://php.net/manual/en/function.date.php

-reference
DatePeriod class:A date period allows iteration over a set of dates and times, recurring at regular intervals, over a given period.
sprintf:Return a formatted string
var_dump: Dumps information about a variable

<?php

require 'Calendar.php';

function h($s){
  return htmlspecialchars($s, ENT_QUOTES, 'UTF-8');
}

$cal = new \MyApp\Calendar();

?>
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Intractive Art</title>
	<meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="styles.css">
	<style>
	</style>
</head>
<body>
  <table>
    <thead>
        <tr>
            <th><a href="/?t=<?php echo h($cal->prev); ?>">&laquo;</a></th>
            <th colspan="5"><a href=""><?php echo h($cal->yearMonth); ?></a></th>
            <th><a href="/?t=<?php echo h($cal->next); ?>">&raquo;</a></th>
        </tr>
    </thead>
    <tbody>
      <tr>
          <td>Sun</td>
          <td>Mon</td>
          <td>Tue</td>
          <td>Wed</td>
          <td>Thu</td>
          <td>Fri</td>
          <td>Sat</td>
      </tr>
      <?php $cal->show(); ?>
    </tbody>
    <tfoot>
      <tr>
          <th colspan="7"><a href="/">Today</a></th>
      </tr>
    </tfoot>
  </table>
	<script>
	</script>
</body>
</html>
<?php

namespace MyApp;

class Calendar {
  public $prev;
  public $next;
  public $yearMonth;
  private $_thisMonth;

  public function __construct(){
    try {
      if(!isset($_GET&#91;'t'&#93;) || !preg_match('/\A\d{4}-\d{2}\z/', $_GET&#91;'t'&#93;)){
        throw new \Exception();
      }
      $this->_thisMonth = new \DateTime($_GET['t']);
    } catch (\Exception $e){
      $this->_thisMonth = new \DateTime('first day of this month');
    }
    $this->prev = $this->_createPrevLink();
    $this->next = $this->_createNextLink();
    $this->yearMonth = $this->_thisMonth->format('F Y');
  }

  private function _createPrevLink(){
    $dt = clone $this->_thisMonth;
    return $dt->modify('-1 month')->format('Y-m');
  }

  private function _createNextLink(){
    $dt = clone $this->_thisMonth;
    return $dt->modify('+1 month')->format('Y-m');
  }

  public function show() {
    $tail = $this->_getTail();
    $body = $this->_getBody();
    $head = $this->_getHead();
    $html = '<tr>' . $tail . $body . $head . '</tr>';
    echo $html;
  }
   private function _getTail(){
     $tail = '';
     $lastDayOfPrevMonth = new \DateTime('last day of ' . $this->yearMonth . ' -1 month');
     while($lastDayOfPrevMonth->format('w') < 6){
       $tail = sprintf('<td class="gray">%d</td>', $lastDayOfPrevMonth->format('d')) .
       $tail;
       $lastDayOfPrevMonth->sub(new \DateInterval('P1D'));
     }
     return $tail;
   }

   private function _getBody(){
     $body = '';
     $period = new \DatePeriod(
       new \DateTime('first day of' . $this->yearMonth),
       new \DateInterval('P1D'),
       new \DateTime('first day of ' . $this->yearMonth . ' +1 month')
     );
     $today = new \DateTime('today');
     foreach($period as $day){
       if ($day->format('w') === '0') { $body .= '</tr><tr>';}
       $todayClass = ($day->format('Y-m-d') === $today->format('Y-m-d')) ? 'today' : '';
       $body .= sprintf('<td class="youbi_%d %s">%d</td>', $day->format('w'),
       $todayClass, $day->format('d'));
     }
     return $body;
   }
   private function _getHead() {
     $head = '';
     $firstDayOfNextMonth = new \DateTime('first day of ' . $this->yearMonth . ' +1 month');
     while ($firstDayOfNextMonth->format('w') > 0) {
       $head .= sprintf('<td class="gray">%d</td>', $firstDayOfNextMonth->format('d'));
       $firstDayOfNextMonth->add(new \DateInterval('P1D'));
     }
     return $head;
   }
}






// $yearMonth = $thisMonth->format('F Y');
body {
  font-family: Arial, sans-serif;
  font-size: 14px;
}
a {
  text-decoration: none;
}
table {
  margin: 15px auto;
  border: 1px solid #ddd;
  border-collapse: collapse;
}
th {
  background: #eee;
}
th, td {
  padding: 7px;
  text-align: center;
}

.youbi_0{
  color: red;
}
.youbi_6 {
  color: blue;
}
.today {
  font-weight: bold;
}
.gray {
  color: #dedede;
}