axiac@web

Do You Clone the DateTime Objects?

The DateTime class and its friends introduced in PHP 5.2 are a very nice replacement for the old date & time processing functions (date(), getdate(), strftime(), strtotime() and so on).

But they come with a minor glitch that is hidden in the plain sight: they are objects and as all the other objects in PHP, they are assigned and passed as parameters by reference[1] and not as copies.

Most of the time I think of a DateTime as a Value Object, passing it from here to there without special precautions. And most of the times this works just fine as long as the code doesn’t try to change it.

When it starts wreaking havoc I remember that DateTime is a class, the instances of it are objects and are passed by reference[1] both as method arguments and as their return values. And special precautions needs to be taken when a method starts modifying a DateTime instance that was not created by the same object (because the one that created it might still hold a reference to it).

The bottom line: always clone the DateTime objects that were not created by the current function when you intend to change them.

Later edit (August 2017)

Since PHP 5.5 it’s better to use DateTimeImmutable objects whenever it’s possible. They cannot be modified after they are created (they behave like true Value Objects). The methods declared in DateTimeInterface that modify the DateTime objects automatically create and return clones for DateTimeImmutable objects.

PHP 5.5 was 20 months old at the time when I wrote this post, but I was still working with PHP 5.3 and PHP 5.4 because of the business constraints.


[1] The PHP documentation explains that they are not really references but different variables storing the same object identifier (which involves an additional redirection layer). This makes them work more like pointers but this is just an implementation detail. From the outside they look like they are passed by reference.

Comments