spatie/once
A tiny PHP helper to run code only once per request. Cache expensive computations or object initialization in a single spot, keyed automatically by the call site. Great for computed properties, accessors, and avoiding duplicate work.
Start by installing the package via Composer: composer require spatie/once. The core API is simplicity itself: wrap any expensive operation in Once::cache() with a unique ID and a closure. For example:
$result = Once::cache('expensive_lookup', fn() => expensiveComputation());
The first call executes the closure; subsequent calls with the same ID return the cached result. In Laravel, this works out-of-the-box in service providers, model accessors, or middleware—no configuration required. Begin by identifying repeated expensive calls (e.g., config parsing, API lookups) and memoizing them.
public function getCustomerScoreAttribute()
{
return Once::cache('customer_score_'.$this->id, fn() => $this->calculateScore());
}
$config = Once::cache('app_config', fn() => json_decode(file_get_contents('config.json'), true));
boot():Once::cache('register_custom_extensions', fn() => $this->registerExtensions());
Once::flush() or script termination.md5($data) unless the data is stable and consistent across calls. Prefix IDs (e.g., 'user_' . $userId) to avoid collisions.Once caches the result, not recomputes if dependencies change. Prefer pure functions or ensure closure inputs are stable.Once::flush() in your test fixtures (e.g., setUp() or between data provider rows) to reset state and avoid false positives.AppServiceProvider::register(), but avoid caching resolved instances that depend on transient state (e.g., Request).$a + $b), the overhead of Once::cache() may outweigh the benefit. Use it only for genuinely expensive ops (I/O, loops, recursions).How can I help you explore Laravel packages today?