spatie/once v3 has been released, now uses a PHP 8 WeakMap
I've just released a new major version of the spatie/once package. This version uses the WeakMap
class which is introduced in PHP 8. In this short post I'd like explain why this change was made.
Introducing the once package
The package offers a once
function. The function can be used to easily cache results of expensive code. You can pass a closure to once
. That closure will only be executed once, no matter how many times the function it resides it is called. Here's an example.
class MyClass {
public function getRandomNumber(): int
{
return once(function () {
return rand();
});
}
};
$myObject = new MyClass();
$myObject->getRandomNumber(); // returns a random number
$myObject->getRandomNumber(); // will return the same number
No matter how many times you run $myObject->getRandomNumber()
inside the same process you'll always get the same number.
Using some reflection magic once
know the object and function it is called in. The cache used behind the scenes scopes all result according to the object it is called on.
Using our example class above, when we call getRandomNumber
on a new instance, we get a new random number.
$myObject = new MyClass();
$myObject->getRandomNumber(); // returns a random number
$myObject->getRandomNumber(); // returns same number as line above
$myOtherObject = new MyClass();
$myOtherObject->getRandomNumber(); // returns a new random number
$myOtherObject->getRandomNumber(); // returns same number as line above
This behaviour is achieved using a WeakMap
. Very shortly said, a WeakMap provides array like behaviour, but instead of using integers and strings as keys, it uses objects. When an object goes out of scope, the related entries in the WeakMap
are automatically removed as well.
In this video I'll show you what a WeakMap
is and how we use it inside the package.
In v2
of spatie/once
we achieved WeakMap
-like behaviour by performing some dark magic to detect when an object goes out of scope. I'm glad that we don't have to maintain this logic anymore.
By refactoring to using a WeakMap
and PHP 8 types we got lose a quite a bit of code. You can see the changes in this PR. The packages now feels much more lighter.
Credits for the idea of the once
function goes to Taylor Otwell. The code for this package is based upon the code he was kind enough to share with us a couple of years ago.
What are your thoughts on "spatie/once v3 has been released, now uses a PHP 8 WeakMap"?