忍者ブログ

VB.NET-TIPS などプログラミングについて

VB.NETのTIPS(小技集)を中心に、Javascript、PHP その他のプログラミングについて少し役に立つ情報を発信します。いわゆる個人的な忘備録ですが、みなさんのお役に立てれば幸いです。

PHP DateTimeクラス(オブジェクト)のコピーについて


DateTime クラス(オブジェクト)は良く使うクラスですが、コピーについては注意が必要なことがあります。

以下のソースを見て下さい。単に「$datetime1」に日付を設定し「$datetime2」にコピーをしています。

<?php
$datetime1 = new DateTime('2022-11-20 10:30:00');
$datetime2 = $datetime1;
$datetime2->modify('+1 day');
echo "\$datetime1 = ".$datetime1->format('Y-m-d')."<br>\n";
echo "\$datetime2 = ".$datetime2->format('Y-m-d')."<br>\n";
?>


これを実行するとブラウザに以下の様に表示されます。

$datetime1 = 2022-11-21
$datetime2 = 2022-11-21


「$datetime2」にコピーをしているので「$datetime1」に影響しないと思いきや、「$datetime2」に modify メソッドで日付を1日加算すると 「$datetime1」「$datetime2」共に同じ日付になります。

「$datetime2」へのコピーでは参照渡しの様な感じになる様です。(実際のPHPの中では参照では無い様ですが…)

そこで、これを解消するにはクローン命令で別のインスタンスを作成し「$datetime2」に代入する必要があります。

<?php
$datetime1 = new DateTime('2022-11-20 10:30:00');
$datetime2 = clone $datetime1;
echo "\$datetime1 = ".$datetime1->format('Y-m-d')."<br>\n";
echo "\$datetime2 = ".$datetime2->format('Y-m-d')."<br>\n";
$datetime2->modify('+1 day');
echo "\$datetime2 = ".$datetime2->format('Y-m-d')."<br>\n";
?>


これを実行するとブラウザに以下の様に表示されます。

$datetime1 = 2022-11-20
$datetime2 = 2022-11-20
$datetime2 = 2022-11-21


modifyadd メソッドの戻り値は自分自身の DateTime オブジェクトを返します。
実際 PHP の正規のマニアルには以下の様に記述されています。

戻り値:
メソッドチェインに使う、変更された DateTime オブジェクトを返します。

メソッドチェイン とは以下の様な使い方です。

<?php
$datetime1 = new DateTime('2022-11-30 10:30:00');
echo "\$datetime1 = ".$datetime1->modify('+1 day')->format('Y-m-d')."<br>\n";
echo "\$datetime1 = ".$datetime1->modify('+1 day')->modify('+1 day')->format('Y-m-d')."<br>\n";
echo "\$datetime1 = ".$datetime1->format('Y-m-d')."
\n"; ?>

3行目では modify メソッドの直後に format メソッドを呼出しています。modifyDateTime オブジェクトを返すので、この方法が可能です。 さらに、4行目では modify メソッドの直後に再度 modify メソッドを呼出しています。
実行結果は以下の様に表示されます。 5行目では再度「$datetime1」の値を表示していますが、3回の modify の実行で日付は初期値から3日後になります。 modify では自分のオブジェクトを変更することがわかります。

$datetime1 = 2022-12-01
$datetime1 = 2022-12-03
$datetime1 = 2022-12-03



ところで DateTime の値を変更する modify メソッド等で新しい DateTime オブジェクトを返したい場合には DateTimeImmutable クラスを使用します。Immutable(イミュータブル) とは「不変」「変わらない」ことを意味するそうです。
では DateTimeImmutable クラスを使用して最初のソースを変更します。

<?php
$datetime1 = new DateTimeImmutable('2022-11-20 10:30:00');
$datetime2 = $datetime1->modify('+1 day');;
echo "\$datetime1 = ".$datetime1->format('Y-m-d')."<br>\n";
echo "\$datetime2 = ".$datetime2->format('Y-m-d')."<br>\n";
?>

実行結果は以下の様に表示されます。 「$datetime1」の modify メソッドの結果は別のオブジェクトとして「$datetime2」に設定された様です。 ただし、「$datetime1」の値は変化がありません。

$datetime1 = 2022-11-20
$datetime2 = 2022-11-21











PR

コメント

コメントを書く