Seeding Fixtures Performance0:01
I have here a class called PostFixtures. If you've been following along with my forum series, you'll recognize it immediately. And in the GetFixturesStatic method, what we're reaching into the file system to grab example posts that we can seed our database with that are a little more realistic than what we'd get through Faker. The problem is, by reaching into the file system, we're increasing the amount of time it takes to execute this code. It's not significant, but it's enough. And we call GetFixtures a lot. In fact, if I dump out, and let's dump here, and we'll run php artisan db:seed, you can see currently we're calling GetFixtures.
Memoization Strategy Overview0:36
In fact, if I dump out, and let's dump here, and we'll run php artisan db:seed, you can see currently we're calling GetFixtures 10 times. That might increase in the future. So we need to think about a caching strategy, because once we've collected these files once, we don't need to do it again. There aren't going to be changes in the request lifecycle. This technique is known as memoization, and you've probably done it before using class properties. You might say private static and let's have a collection called fixtures. And then inside here, we say, well, do I have any fixtures? If I do
Using Laravel once()1:08
and let's have a collection called fixtures. And then inside here, we say, well, do I have any fixtures? If I do return those, otherwise set fixtures equal to the result of this collection pipeline. And then in the future, it's only going to return that once. In Laravel 11, we can simplify logic like this, because there is a very useful new once function. Let's get rid of the code we've just created, and I'll make use of that once function. It's available globally, and it expects a callable. So we'll pass in a closure, and of course, I'll wrap the entire thing
It's available globally, and it expects a callable. So we'll pass in a closure, and of course, I'll wrap the entire thing inside that closure. Now, let me prove this to you. I'll convert into a traditional closure, and before we return this collection, I'll dump out here once again. Let's also get rid of this private static property that we introduced. Okay, with that in place, let's seed our database once more, php artisan db:seed, and note that even though we made no changes to the seeder, in other words, we're still calling getFixtures ten times, we only dump once. And that's because as soon as Laravel has executed this
Request Macro with once()2:12
getFixtures ten times, we only dump once. And that's because as soon as Laravel has executed this closure one time, it caches the result, and it will return that on subsequent requests. So, that's one example. Why don't we take a look at another? In the AppServiceProvider, let's say we want to extend the request. So, Illuminate\Support\Facades\Request, I'm going to create a macro called identifier, and what we want is a unique identifier for each request that comes in. In order to support this, we can make use of the once function. I'll say return once, and inside
request that comes in. In order to support this, we can make use of the once function. I'll say return once, and inside here, let's have a closure that returns, I don't know, a string UUID, so Illuminate\Support\Str::uuid. And with that implemented, no matter how many times we call identifier on the request object, we will always receive the same value inside the lifecycle of a request. Let me show you. In web.php, for our homepage, let's accept the request object, and I'm just going to dump out the requestIdentifier method.
homepage, let's accept the request object, and I'm just going to dump out the RequestIdentifier method. Let's duplicate this several times, and then let's load it on the frontend. Note that every time we call Identifier, yes, it returns the UUID, but the UUID is identical every single time because of the memorization that's taking place inside that once function that Laravel provides, and the only time it will change is when a new request comes in. If I refresh the page to simulate that, of course the Identifier is different. One important thing to note is that
once() Instance Caching3:48
comes in. If I refresh the page to simulate that, of course the Identifier is different. One important thing to note is that different instances of the same class will cache separately. So here I have an example class that simply returns a string UUID. Inside the root, I'm going to instantiate that class twice. One for exampleOne, and again for exampleTwo. Then I'll dump out exampleOne twice, and I'll dump out exampleTwo twice. Note that both instances of exampleOne are identical, BA2DD4F8 and BA2DD4F8. However, as soon as we
of example one are identical, BA2DD4F8 and BA2DD4F8. However, as soon as we switch over to example two, the UUID has changed because we're dealing with a separate class instance. So how cool is that? A super simple once function that you can use anywhere in the code base to ensure that no matter how many times you execute that code in the life cycle of a request, it will only actually perform it once, and then the value will be returned to you. I can think of so many places in my projects where I can refactor to use once.
returned to you. I can think of so many places in my projects where I can refactor to use once.
