Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Once Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

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.

Implementation Patterns

  • Method Memoization in Models: Cache derived attributes in accessors to avoid recomputing on every property access:
public function getCustomerScoreAttribute()
{
    return Once::cache('customer_score_'.$this->id, fn() => $this->calculateScore());
}
  • Configuration Loading: Load and parse config files once per request:
$config = Once::cache('app_config', fn() => json_decode(file_get_contents('config.json'), true));
  • Service Provider Optimizations: Avoid repeated heavy setup in boot():
Once::cache('register_custom_extensions', fn() => $this->registerExtensions());
  • Middleware & Job Contexts: Cache computed values across multiple job/requests where state persists (e.g., within a Laravel queue job), but remember cache is request-scoped, not global.

Gotchas and Tips

  • Request-Scoped Only: Cache lives only within a single PHP request lifecycle. Don’t expect persistence across HTTP requests or CLI invocations—this is not a Redis/DB cache. Reset occurs on Once::flush() or script termination.
  • ID Uniqueness Matters: IDs must be globally unique per use case. Avoid dynamic IDs like md5($data) unless the data is stable and consistent across calls. Prefix IDs (e.g., 'user_' . $userId) to avoid collisions.
  • Stateful Closures Can Break It: Never close over mutable variables that change between calls—Once caches the result, not recomputes if dependencies change. Prefer pure functions or ensure closure inputs are stable.
  • Testing Tip: Use Once::flush() in your test fixtures (e.g., setUp() or between data provider rows) to reset state and avoid false positives.
  • Laravel Tip: Works seamlessly with Laravel’s service container. Memoize expensive bindings in AppServiceProvider::register(), but avoid caching resolved instances that depend on transient state (e.g., Request).
  • Performance Edge Case: For trivially fast operations (e.g., $a + $b), the overhead of Once::cache() may outweigh the benefit. Use it only for genuinely expensive ops (I/O, loops, recursions).
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport