PHPackages                             splitstack/laravel-stashable - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Caching](/categories/caching)
4. /
5. splitstack/laravel-stashable

ActiveLibrary[Caching](/categories/caching)

splitstack/laravel-stashable
============================

An attribute-based caching system for repositories

1.0.1(10mo ago)1164↓86.7%MITPHPPHP ^8.1CI failing

Since Aug 14Pushed 2mo ago1 watchersCompare

[ Source](https://github.com/EmilienKopp/Stashable)[ Packagist](https://packagist.org/packages/splitstack/laravel-stashable)[ RSS](/packages/splitstack-laravel-stashable/feed)WikiDiscussions main Synced today

READMEChangelog (1)Dependencies (3)Versions (3)Used By (0)

Laravel Stashable
=================

[](#laravel-stashable)

[![Tests](https://camo.githubusercontent.com/3eb323574e78f1c9c57bf60af2629d92f7b31b116c77ead5fff875aca78ca776/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f656d696c69656e6b6f70702f737461736861626c652f74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/emilienkopp/stashable/actions/workflows/tests.yml)

[![PHP Version](https://camo.githubusercontent.com/bf4bda9d4d0ed45dda848717371d8b1854e1002a3d0bf0990030ff55b143d5c9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253345253344382e312d626c75653f7374796c653d666c61742d737175617265)](https://www.php.net)[![Laravel Version](https://camo.githubusercontent.com/ec554dce86de444b48b80d529e5b6222689897faa5c84428a0a72cc55c194fdc/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c61726176656c2d31302e7825374331312e782d7265643f7374796c653d666c61742d737175617265)](https://laravel.com)[![License: MIT](https://camo.githubusercontent.com/1b01ef0024ba0866c115986b895301f657c1b21fc29f05c4844b7f2e8d89204d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e7376673f7374796c653d666c61742d737175617265)](https://opensource.org/licenses/MIT)[![Total Downloads](https://camo.githubusercontent.com/5240ceb9cd92f47e9f82ac002e2b19b3077b189aafc55a2ce7ecb95714aa8934/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f73706c6974737461636b2f6c61726176656c2d737461736861626c652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/splitstack/laravel-stashable)

An elegant attribute-based caching system for Laravel repositories. Simplify your repository caching with powerful attributes and flexible cache management.

Mention
-------

[](#mention)

This package is part of the (WIP) **Splitstack** suite, a collection of tools and packages to help you build better Laravel applications. Stay tuned for more packages and updates!

Features
--------

[](#features)

- 🎯 **Attribute-Based Caching**: Declaratively cache repository methods using PHP attributes
- 🔑 **Smart Cache Keys**: Automatically includes method arguments and query parameters
- 🏷️ **Cache Tags Support**: Group related cache entries for bulk operations
- 🔄 **Flexible Cache Operations**: Choose between cached, fresh, or refreshed data
- 🛠️ **Developer Friendly**: Simple integration with existing repositories
- ⚡ **Performance Optimized**: Minimize database hits while keeping data fresh

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require splitstack/laravel-stashable
```

Usage
-----

[](#usage)

1. Add the `Stashable` trait to your repository:

```
use Splitstack\Stashable\Traits\Stashable;

class UserRepository
{
    use Stashable;

    #[WithCache('user.all')] // Cache key: user.all
    public function getAll()
    {
        return User::all();
    }

    #[WithCache(ttl: 3600)] // Cache for 1 hour
    public function getById($id)
    {
        return User::find($id);
    }

    #[WithCache(key: 'role_{0}')] // key: role_admin
    public function getByRole($role)
    {
        return User::where('role', $role)->get();
    }

    #[WithCache(key: 'search.{0}.{1}')] // key: search.department.seniority
    public function searchDepartment($department, $seniority)
    {
        return Product::where('department', $department)
                      ->where('seniority', $seniority)
                      ->get();
    }

    #[WithCache(key: 'search.{company}.{position}')] // key: search.github.engineer
    public function searchCompany($company, $position)
    {
        return Product::where('department', $department)
                      ->where('position', $position)
                      ->get();
    }
}
```

2. Use the caching methods:

```
// Get cached result (creates cache if doesn't exist)
$users = UserRepository::cache('getAll');

// Get fresh result (bypasses cache)
$user = UserRepository::fresh('getById', 1);

// Get cached result without creating cache if missing
$users = UserRepository::get('getAll');

// Refresh cache with fresh data
$users = UserRepository::refresh('getAll');
```

3. Default values:

The TTL is set in `config/stashable.php` as 60 seconds by default. Keys will always default to the `singular model name` + `method name`. e.g.: `UserRepository::getAll()` will default to `user.getAll` if no key is provided in the `#[WithCache]` attribute.

Tenant-Aware Caching
--------------------

[](#tenant-aware-caching)

Stashable supports multi-tenant applications with automatic cache isolation between tenants. When enabled, cache keys are automatically prefixed with the current tenant identifier.

### Installation for Multi-Tenancy

[](#installation-for-multi-tenancy)

First, install Spatie Laravel Multitenancy (recommended):

```
composer require spatie/laravel-multitenancy
```

Then publish and configure Stashable:

```
php artisan vendor:publish --tag=stashable-config
```

### Configuration

[](#configuration)

Configure tenant awareness in `config/stashable.php`:

```
return [
    // Enable tenant-aware caching
    'tenant_aware' => true,

    // Detection methods (tried in order)
    'tenant_detection_methods' => [
        'spatie',    // Use Spatie Laravel Multitenancy
        'route',     // Extract from route parameter
        'subdomain', // Extract from subdomain
        'header',    // Extract from HTTP header
        'session',   // Extract from session
    ],

    // Route parameter name for tenant detection
    'tenant_route_parameter' => 'tenant',

    // HTTP header name for tenant detection
    'tenant_header_name' => 'X-Tenant-ID',

    // Session key for tenant detection
    'tenant_session_key' => 'tenant_id',
];
```

### Usage with Tenants

[](#usage-with-tenants)

Once configured, your cached repository methods automatically become tenant-aware:

```
// Tenant 1 context
$users = UserRepository::cache('getAll'); // Cached as: tenant_1.user.getAll

// Tenant 2 context
$users = UserRepository::cache('getAll'); // Cached as: tenant_2.user.getAll
```

### Tenant Cache Management

[](#tenant-cache-management)

Flush cache for specific tenants:

```
// Flush cache for current tenant
UserRepository::flushTenantCache();

// Flush cache for specific tenant
UserRepository::flushTenantCacheFor('tenant-123');

// Get tenant cache statistics
$stats = UserRepository::getTenantCacheStats();
```

### Console Commands

[](#console-commands)

Manage tenant cache via Artisan commands:

```
# Flush cache for current tenant
php artisan stashable:tenant-cache flush

# Flush cache for specific tenant
php artisan stashable:tenant-cache flush --tenant=123

# View tenant cache statistics
php artisan stashable:tenant-cache stats
```

### Cache Tags

[](#cache-tags)

You can tag cache entries for bulk operations:

```
#[WithCache(tags: ['users', 'roles'])]
public function getByRole($role)
{
    return User::where('role', $role)->get();
}

// Clear all caches with 'roles' tag
Cache::tags(['roles'])->clear();
```

### Query Parameters (beta)

[](#query-parameters-beta)

Cache keys can append query parameters **from the Request facade** if `useQuery` is set to `true`, ensuring different results for different query contexts:

```
#[WithCache(key:'search', useQuery: true)] // key: search?department=HR&seniority=Junior
public function search()
{
  $query = Request::query();
  return //... your search query
}
```

Testing
-------

[](#testing)

```
composer test
```

Security
--------

[](#security)

If you discover any security related issues, please email the author instead of using the issue tracker.

Credits
-------

[](#credits)

- [EmilienKopp](https://github.com/EmilienKopp)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance71

Regular maintenance activity

Popularity12

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

323d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/b9e77e55bb8341a1fa99f8348597070b4de230b5fc457e866e4f196dd56843f1?d=identicon)[EmilienKopp](/maintainers/EmilienKopp)

---

Top Contributors

[![EmilienKopp](https://avatars.githubusercontent.com/u/91975560?v=4)](https://github.com/EmilienKopp "EmilienKopp (24 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/splitstack-laravel-stashable/health.svg)

```
[![Health](https://phpackages.com/badges/splitstack-laravel-stashable/health.svg)](https://phpackages.com/packages/splitstack-laravel-stashable)
```

###  Alternatives

[unopim/unopim

UnoPim Laravel PIM

10.5k2.4k](/packages/unopim-unopim)[statamic-rad-pack/runway

Eloquently manage your database models in Statamic.

135224.7k7](/packages/statamic-rad-pack-runway)[api-platform/laravel

API Platform support for Laravel

58171.4k14](/packages/api-platform-laravel)[ecotone/laravel

Ecotone for Laravel — CQRS, Event Sourcing, Sagas, Durable Workflows, and Outbox on top of Laravel Queue, via PHP attributes.

21318.6k3](/packages/ecotone-laravel)[duncanmcclean/statamic-cargo

Comprehensive e-commerce addon for Statamic. Build bespoke e-commerce sites without the complexity.

3416.9k](/packages/duncanmcclean-statamic-cargo)[byerikas/cache-tags

Allows for Redis/Valkey cache flushing multiple tagged items by a single tag.

1420.4k](/packages/byerikas-cache-tags)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
