Laravel 5.8 was released last week, adding in support for Carbon 2.0 (among other things!). Carbon 2.0 includes a class called
CarbonImmutable which allows us to use immutable date objects. To get a better idea of what that means, you can read the Carbon docs. The bits we’re interested in are:
We also provide CarbonImmutable class extending DateTimeImmutable. The same methods are available on both classes but when you use a modifier on a Carbon instance, it modify it and returns the same instance, when you use it on CarbonImmutable, it returns a new instances with the new value.
And here’s the examples they give us:
I’m a huge fan of immutable data structures (I won’t get into why in this post, there’s plenty of other resources out there explaining the benefits of immutable data), so I was excited to give this a go.
However, it wasn’t immediately obvious how to get this to work in Laravel. A blog post on laravel-news showed off the ability but didn’t go into how to set it up, so I went about working out and decided to write this post so others in the same position can find it.
Before we start, it’s worth noting that these changes will make Laravel use CarbonImmutable by default. Which means this could be a breaking change if your project is already using the mutable version of Carbon. Let’s get started!
First, we need to tell Laravel that we plan to use CarbonImmutable. Of course, we do this in a service provider. You can create your own or just use the default AppServiceProvider.
register method of your service provider, we need to use the new Laravel
Date facade to tell Laravel that we want to use the new
Carbon\CarbonImmutable class by default. The
Date facade has a
use method that we can pass either a callable, a class name, or a
Factory instance. We want to just pass it a class name:
And that’s it — if we use the
Date facade to create dates, they will use
CarbonImmutable under the hood!
It’s important to know that for this to work, you need to use the facade now. In the past I have used
Carbon by importing it directly from the package, which of course won’t work as it won’t be configured:
I hope this helps, thanks for reading!