Carbonとは
PHPの日付操作で使われるライブラリ。
Laravelに標準で入っている。
ミュータブル・イミュータブルとは
ミュータブル
→ 可変
イミュータブル
→ 不変
ミュータブルの例(Carbon)
$date = new \Carbon\Carbon('2018-01-01');
$nextYear = $date->addYear(); // 1年加算する
echo $nextYear->format('Y-m-d');
// -> ???
ミュータブルの例(Carbon)
$date = new \Carbon\Carbon('2018-01-01');
$nextYear = $date->addYear(); // 1年加算する
echo $nextYear->format('Y-m-d');
// -> ???
→ 2019-01-01
ミュータブルの例(Carbon)
$date = new \Carbon\Carbon('2018-01-01');
$nextYear = $date->addYear();
echo $nextYear->format('Y-m-d');
// -> 2019-01-01
echo $date->format('Y-m-d');
// -> ???
ミュータブルの例(Carbon)
$date = new \Carbon\Carbon('2018-01-01');
$nextYear = $date->addYear();
echo $nextYear->format('Y-m-d');
// -> 2019-01-01
echo $date->format('Y-m-d');
// -> ???
→ 2019-01-01
addYear()
メソッドが$date
自体を変更している!
イミュータブルの例(CarbonImmutable)
$date = new \Carbon\CarbonImmutable('2018-01-01');
$nextYear = $date->addYear();
echo $nextYear->format('Y-m-d');
// -> ???
イミュータブルの例(CarbonImmutable)
$date = new \Carbon\CarbonImmutable('2018-01-01');
$nextYear = $date->addYear();
echo $nextYear->format('Y-m-d');
// -> ???
→ 2019-01-01
イミュータブルの例(CarbonImmutable)
$date = new \Carbon\CarbonImmutable('2018-01-01');
$nextYear = $date->addYear();
echo $nextYear->format('Y-m-d');
// -> 2019-01-01
echo $date->format('Y-m-d');
// -> ???
イミュータブルの例(CarbonImmutable)
$date = new \Carbon\CarbonImmutable('2018-01-01');
$nextYear = $date->addYear();
echo $nextYear->format('Y-m-d');
// -> 2019-01-01
echo $date->format('Y-m-d');
// -> ???
→ 2018-01-01
addYear()
メソッドが$date
自体を変更していない!
ミュータブルとイミュータブルの違い
$date = new \Carbon\Carbon('2018-01-01');
$date->addYear();
echo $date->format('Y-m-d'); // -> 2019-01-01
// 元のオブジェクトが変更されてしまっている😱
$date = new \Carbon\CarbonImmutable('2018-01-01');
$date->addYear();
echo $date->format('Y-m-d'); // -> 2018-01-01
// 元のオブジェクトが変更されていない!
ここまでのまとめ
- ミュータブルな操作とは元のオブジェクトの変更を伴う操作である。
- ミュータブルな操作は破壊的とも呼ばれることがある。
- ミュータブルな操作は想定しない挙動を起こすことがあるため、安全性が低いとされている。
→ 「ミュータブル」とか「破壊的メソッド」とか調べると色々な記事が出てきます。
問題
第一問
ミュータブルな操作
$date = new \Carbon\Carbon('2018-01-01');
$nextYear = $date; // 代入する
$nextYear->addYear();
echo $nextYear->format('Y-m-d');
// -> 2019-01-01
echo $date->format('Y-m-d');
// -> ???
第一問
ミュータブルな操作
$date = new \Carbon\Carbon('2018-01-01');
$nextYear = $date; // 代入する
$nextYear->addYear();
echo $nextYear->format('Y-m-d');
// -> 2019-01-01
echo $date->format('Y-m-d');
// -> ???
→ 2019-01-01
ただ代入するだけでは参照渡しになってしまう!
第二問
Carbonのままイミュータブルに操作するには?
$date = new \Carbon\Carbon('2018-01-01');
$nextYear = $date;
$nextYear->addYear();
echo $nextYear->format('Y-m-d'); // -> 2018-01-01
echo $date->format('Y-m-d'); // -> 「2018-01-01」と表示されるようにしたい!
第二問
Carbonのままイミュータブルに操作するには?
$date = new \Carbon\Carbon('2018-01-01');
- $nextYear = $date;
+ $nextYear = clone $date;
$nextYear->addYear();
echo $nextYear->format('Y-m-d'); // -> 2018-01-01
echo $date->format('Y-m-d'); // -> 2018-01-01
→ clone
を使おう!
cloneとは
→ 親オブジェクトをコピーする際に、そのコピーが独立したオブジェクトの コピーを有するように、そのオブジェクトのインスタンスを新たに作成したい場合