【備忘録】DatePeriodクラスとforeachの関係性を理解する

#目的
以下のコードを理解する。カレンダー機能の日付を作成しようとしている。

```ruby:tdを作る
<?php

$body = '';
$period = new DatePeriod(
    new DateTime('first day of this month'),
    new DateInterval('P1D'),
    new DateTime('first day of next month')
);
foreach ($period as $day) {
    $body .= sprintf('<td>%d</td>',$day->format('d'));
}
?>
```

#参考資料
PHP公式ドキュメント
・[DatePeriod クラス](https://www.php.net/manual/ja/class.dateperiod.php)
・[DateTime クラス](https://www.php.net/manual/ja/class.datetime.php)
・[DateInterval クラス]
(https://www.php.net/manual/ja/class.dateinterval.php)


##DateTimeクラスとは

日付と時刻をあらわします。

[相対的な書式](https://www.php.net/manual/ja/datetime.formats.relative.php)を用いることで、ほしい日付情報が取れる。何もかかないと、現在の日付情報が取得できる。~~***返り値は、連想配列である。***~~

【追記】
[var_dump](https://www.php.net/manual/ja/function.var-dump.php)について、間違った解釈してました。







```ruby:例1DateTime
$datetime = new DateTime('first day of this month');
var_dump($datetime);

$datetime1 = new DateTime();
var_dump($datetime1);
```

```ruby:DateTimeの出力
//今月の月時刻
object(DateTime)#1 (3) { ["date"]=> string(26) "2019-10-01 01:31:24.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(10) "Asia/Tokyo" }


//現在の時刻
object(DateTime)#1 (3) { ["date"]=> string(26) "2019-10-20 01:35:11.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(10) "Asia/Tokyo" }
```

これぱっとみ勝手に配列と思ってたけど、`object(DateTime)`って書かれてるし、***public、private および protected なプロパティを出力してるんだろうなー***

##DateIntervalとは
>日付の間隔をあらわします。

>格納方式は、固定値 (年、月、日、時など) あるいは相対時刻 (DateTime のコンストラクタがサポートしている書式) となります。


`
~~DateIntervalクラスを使用すると、返り値の要素に代入される値は、固定か、相対時刻ってことかな、、、~~

よくわからん

とりあえず、var_dumpしてみた

```ruby:DateInterval
$interval = new DateInterval('P1D');
var_dump($interval);
```


```ruby:DateInterval出力
object(DateInterval)#1 (15) {
  ["y"]=>
  int(0)
  ["m"]=>
  int(0)
  ["d"]=>
  int(1)
  ["h"]=>
  int(0)
  ["i"]=>
  int(0)
  ["s"]=>
  int(0)
  ["weekday"]=>
  int(0)
  ["weekday_behavior"]=>
  int(0)
  ["first_last_day_of"]=>
  int(0)
  ["invert"]=>
  int(0)
  ["days"]=>
  bool(false)
  ["special_type"]=>
  int(0)
  ["special_amount"]=>
  int(0)
  ["have_weekday_relative"]=>
  int(0)
  ["have_special_relative"]=>
  int(0)
}
```

`["d"]=>int(1)`と表示されるのは、引数に`P1D`を記述して、1日間隔を指定したからだはず。

***ちなみに、引数に何も入れないとエラーになる***

・・・こいつの使い方よくわからねー！！！:sob:

##DatePeriodとは
こいつが、DateTimeとDateIntervalを繋げる役割してるのかな、、

>日付の期間をあらわします。

>日付の期間を使うと、指定した期間に定期的に発生する内容を反復処理できます。

`反復処理`がよくわからないなー、

ドキュメント読んでみると、
コンストラクターの書き方が３パターンあるみたいだけど、冒頭のコードは以下の書き方を適用している

```ruby:DatePeriod引数
public __construct ( DateTimeInterface $start , DateInterval $interval , DateTimeInterface $end [, int $options ] )

```

DateTimeInterfaceってのは、***型宣言?***ことであり、これは、DateTimeInterfaceクラスが関係しているものじゃないと、引数に代入できないですよ〜って意味。

ちなみに、[DateTime](https://www.php.net/manual/ja/class.datetime.php)クラスのコードを見てみると、***`implements`で`DateTimeInterface`を継承しており、すでに型宣言されている　***ため,```DatePeriod```の引数に使用できる

冒頭に記述したDatePeriodを出力してみると、
以下のようになる

```ruby:DatePeriodクラス
$period = new DatePeriod(
    new DateTime('first day of this month'),
    new DateInterval('P1D'),
    new DateTime('first day of next month')
);
var_dump($period);
```
```ruby:DatePeriod出力
 object(DatePeriod)#1 (6) { 
:--
   ["start"]=> 
   object(DateTime)#2 (3) { 
     ["date"]=> 
     string(26) "2019-10-01 09:58:53.000000" 
     ["timezone_type"]=> 
     int(3) 
     ["timezone"]=> 
     string(10) "Asia/Tokyo" 
   } 
   ["current"]=> 
   NULL 
   ["end"]=> 
   object(DateTime)#3 (3) { 
     ["date"]=> 
     string(26) "2019-11-01 09:58:53.000000" 
     ["timezone_type"]=> 
     int(3) 
     ["timezone"]=> 
     string(10) "Asia/Tokyo" 
   } 
   ["interval"]=> 
   object(DateInterval)#4 (15) { 
     ["y"]=> 
     int(0) 
     ["m"]=> 
     int(0) 
     ["d"]=> 
     int(1) 
     ["h"]=> 
     int(0) 
     ["i"]=> 
     int(0) 
     ["s"]=> 
     int(0) 
     ["weekday"]=> 
     int(0) 
     ["weekday_behavior"]=> 
     int(0) 
     ["first_last_day_of"]=> 
     int(0) 
     ["invert"]=> 
     int(0) 
     ["days"]=> 
     bool(false) 
     ["special_type"]=> 
     int(0) 
     ["special_amount"]=> 
     int(0) 
     ["have_weekday_relative"]=> 
     int(0) 
     ["have_special_relative"]=> 
     int(0) 
   } 
   ["recurrences"]=> 
   int(1) 
   ["include_start_date"]=> 
   bool(true) 
 } 

```
~~返り値は、連想配列であり、***引数に代入したクラスは、以下のキーとペアになっている***~~
配列ではありません。

```
[start] => new DateTime('first day of this month')
[interval] => new DateInterval('P1D')
[end] => new DateTime('first day of next month')
```

##foreachとDateperiodについて
Dateperiodをforeachで出力すると、以下の結果になる

```ruby:Dateperiodをforeahで出力
$period = new DatePeriod(
    new DateTime('first day of this month'),
    new DateInterval('P1D'),
    new DateTime('first day of next month')
);

foreach ($period as $day) {
    var_dump($day);
}

```


```ruby:var_dump($day)の出力
 object(DateTime)#3 (3) { 
   ["date"]=> 
   string(26) "2019-10-01 19:42:43.000000" 
   ["timezone_type"]=> 
   int(3) 
   ["timezone"]=> 
   string(10) "Asia/Tokyo" 
 } 
 object(DateTime)#4 (3) { 
   ["date"]=> 
   string(26) "2019-10-02 19:42:43.000000" 
   ["timezone_type"]=> 
   int(3) 
   ["timezone"]=> 
   string(10) "Asia/Tokyo" 
 } 
・
・
・
・
 object(DateTime)#4 (3) { 
   ["date"]=> 
   string(26) "2019-10-30 20:56:25.000000" 
   ["timezone_type"]=> 
   int(3) 
   ["timezone"]=> 
   string(10) "Asia/Tokyo" 
 } 
 object(DateTime)#3 (3) { 
   ["date"]=> 
   string(26) "2019-10-31 20:56:25.000000" 
   ["timezone_type"]=> 
   int(3) 
   ["timezone"]=> 
   string(10) "Asia/Tokyo" 
 } 
```


***DateTimeの返り値と同じような構造で、月初から月末までの日付情報を1日間隔で出力する***

みたいだけど、ピンとこない:sob:


DatePeriodの返り値は、
[start],[end],[interval],[その他]なのに、
なんでforeachしただけで、DateTimeみたいな返り値がきれいに出力されるんだ？？？？？？？？？

***Why Dateperiod ???????(厚切りアベ茶)***

foreach理解してないからかなーーー
foreach嫌いだわーーー

##まとめ
foreach嫌い！！！