ascetik / cacheable
Convert Closures and objects into strings
Requires
- ascetik/callapsule: ^0.3.0
- opis/closure: ^3.6
- php-ds/php-ds: ^1.4
Requires (Dev)
- phpunit/phpunit: ^10.4
This package is auto-updated.
Last update: 2025-03-11 13:40:58 UTC
README
Convert Closures and objects to strings in order to provide callable caching
Release notes
v1.0.0 :
- Breaking change : CacheableCall now extends CallableType from ascetik/callapsule package. Methods have been updated to match with required behavior.
- CacheableCall decorates a CallableType.
Purpose
Each time a client switches the page or submits some data, the server has to build whole system, with services, routes, middlewares... I wondered if it was possible to store some instances or functions in cache for faster system build. The main problem was the serialization of a Closure, which may be used by a router or a service container.
A short time was necessary to find the opis/closure package. This was the base to find out how to resolve my problem. This package may be still incomplete. I have to test it in a production context to get some feedback with some logs. Self-made logger package is still not done.
Vocabulary
Cacheable is the main interface. It just extends Serializable interface and nothing else for now. CacheableCall abstracts the idea of a wrapper able to serialize any callable. CacheableInstance extends an instance to be fully serializable. CacheableProperty holds the name and the value of each CacheableInstance wrapped instance.
Descriptions & Exposed Methods
Notice : The use of serialize and unserialize methods is not recommended and will certainly lead to serialization inconsistencies. Use native serialize/unserialize functions instead.
CacheableFactory (not Cacheable itself)
- wrapCall(callable): CacheableCall : Returns a CacheableCall instance
- wrapInstance(object): CacheableInstance : Returns a CacheableInstance instance
- wrapProperty(string, mixed): CacheableProperty : Returns a CacheableProperty
CacheableCall
- action(): callable : Returns registered callable as is
- apply(iterable): mixed : Calls registered callable
CacheableCall is invokable to keep it simple to use on runtime
CacheableInstance
- getClass(): string : Returns registered class name
- getProperties(): Ds\Set : Returns a container of CacheableProperties built from registered instance properties
- getInstance(): object : Returns registered instance
CacheableProperty
- getName(): string : Returns property name
- getValue(): mixed : Returns property value
Usage
Callable Wrap
The CacheableFactory provides methods to build Cacheable instances for callable types. There are three sorts of wrapper to serialize a callable :
// Closure use case $func = function(string $name): string { return 'Closure : hello '.$name; } // class method use case class Greeter { public function greet($name): string { return 'Method : hello ' . $name; } } // invokable class use case class InvokableGreeter { public function __invoke(string $name): string { return 'Invkable : hello ' . $name; } } $closureWrapper = CacheableFactory::wrapCall($func); // returns a CacheableClosure instance $methodWrapper = CacheableFactory::wrapCall(new Greeter()); // returns a CacheableMethod instance $invokableWrapper = CacheableFactory::wrapCall(new InvokableGreeter()); // returns a CacheableInvokable instance
As they all are Cacheable, so Serializable, serialization is easy :
$serial = serialize($closureWrapper);
And unserialization is easy too :
$serial = goAndFindInCache('something-satisfying-my-needs'); // file, external service, SQL, noSQL, hyper-speed keyboard typing world champion... $wrapper = unserialize($serial); echo $wrapper->apply(['John']); // prints 'Closure : hello John' // A CacheableCall is invokable echo $wrapper(['John']); // same result
Instances Wrap
$instance = new MyInstance(); $wrapper = CacheableFactory::wrapInstance($instance); $serial = serialize($wrapper); // get wrapper back $extractedWrapper = unserialize($serial); $extractedInstance = $extractedWrapper->getInstance(); $extractedInstance->doWhatIsExpected(); // Or use the extracted wrapper directly $extractedWrapper->doWhatIsExpected(); $property = $extractedWrapper->someProperty();
When using wrapper magic methods, Exceptions are thrown if :
- called method does not exist
- property does not exist
- property is public
Finalities
This package provides serialization and unserialization. The usage of the output is up to you.