PHPackages                             alyakin/dictionary-cache-service - 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. alyakin/dictionary-cache-service

ActiveLibrary[Caching](/categories/caching)

alyakin/dictionary-cache-service
================================

Dictionary caching service for Redis-compatible stores (Redis, KeyDB, Valkey, etc.).

00PHPCI passing

Since Nov 16Pushed 5mo ago1 watchersCompare

[ Source](https://github.com/2177866/dictionary-cache-service)[ Packagist](https://packagist.org/packages/alyakin/dictionary-cache-service)[ RSS](/packages/alyakin-dictionary-cache-service/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

Dictionary Cache Service
========================

[](#dictionary-cache-service)

[![Latest Stable Version](https://camo.githubusercontent.com/8b83809d3278d96a799103bed09a14da39fad63ce06053df813fc1be8045b5e4/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f616c79616b696e2f64696374696f6e6172792d63616368652d736572766963652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/alyakin/dictionary-cache-service)[![Total Downloads](https://camo.githubusercontent.com/52c9bfc0eb7b88c3699f0d25a15e9a104b9410f6aed0321458be116d2f764ba5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f616c79616b696e2f64696374696f6e6172792d63616368652d736572766963652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/alyakin/dictionary-cache-service)[![CI Status](https://github.com/2177866/dictionary-cache-service/actions/workflows/ci.yml/badge.svg)](https://github.com/2177866/dictionary-cache-service/actions/workflows/ci.yml)[![PHP 7.4+](https://camo.githubusercontent.com/3a89b45c8743b4b0136c10ffbd0985a6e1f8fbcf66cd31097deb4497caa0028b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d372e342532422d626c75652e7376673f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/3a89b45c8743b4b0136c10ffbd0985a6e1f8fbcf66cd31097deb4497caa0028b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d372e342532422d626c75652e7376673f7374796c653d666c61742d737175617265)[![MIT License](https://camo.githubusercontent.com/6c711032aff1ca0eb6b211aa6cb3649ce7fd64a7714e1181d4bb457f9680e7cf/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e2e7376673f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/6c711032aff1ca0eb6b211aa6cb3649ce7fd64a7714e1181d4bb457f9680e7cf/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e2e7376673f7374796c653d666c61742d737175617265)

Dictionary caching based on Redis-compatible stores (Redis, KeyDB, Valkey, Dragonfly, Ardb, etc.).

Contents
--------

[](#contents)

- [Installation](#installation)
- [Examples](#examples)
- [Methods](#methods)
    - [Creating an object](#__construct)
    - [Setup scope for cache](#setcontext)
    - [Set data provider](#setdataprovider)
    - [Set cache Time To Live (TTL)](#setttl)
    - [Get cache Time To Live (TTL)](#getttl)
    - [Manually preload cache](#preload)
    - [Check one item in cache](#hasitem)
    - [What items from the list are in the cache](#hasitems)
    - [Get all elements from cache](#getallitems)
    - [Checking if cache is loaded](#exists)
    - [Manually add elements to cache](#additems)
    - [Manually remove element from the cache](#removeitem)
    - [Reset TTL countdown](#keepalive)
    - [Clear cache for the scope](#clear)
- [Supported Databases](#supported-databases)
- [Requirements](#requirements)
- [Contributing](#want-to-contribute)
- [License](#license)

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

[](#installation)

Install via Composer:

```
composer require alyakin/dictionary-cache-service
```

This package is framework-agnostic: it does not bootstrap a Redis connection on its own. Provide an implementation of `Alyakin\DictionaryCache\Contracts\RedisClientInterface` (or one of the bundled adapters) when constructing the service.

Available adapters:

- `Alyakin\DictionaryCache\Adapters\IlluminateRedisClient` - wrap Laravel's `Redis::connection()`.
- `Alyakin\DictionaryCache\Adapters\PhpRedisClient` - reuse the native `\Redis` / `\RedisCluster` extension.
- Custom implementations - implement the interface if you rely on another Redis library.

Examples
--------

[](#examples)

 ```
flowchart LR
    A[Provider / manual wiring] --> B(DictionaryCacheService)
    B --> C[setContext / setTTL]
    B --> D[setDataProvider]
    D -->|optional| E[(Data source)]
    B --> F[RedisClientInterface]
    F --> G[IlluminateRedisClient]
    F --> H[PhpRedisClient]
    G --> I[(Laravel Redis connection)]
    H --> J[(Redis / KeyDB / Valkey / Dragonfly)]
```

      Loading  ```
sequenceDiagram
    participant Client
    participant Cache as DictionaryCacheService
    participant Provider as Data provider / DB

    Client->>Cache: hasItems(ids)
    Cache-->>Client: cache miss (not initialized)
    Cache->>Provider: preload() fetch dataset
    Provider-->>Cache: array of items
    Cache-->>Client: first response (stored in Redis)

    Client->>Cache: hasItems(ids)
    Cache-->>Client: hit from Redis (no DB call)

    Client->>Cache: hasItems(ids)
    Cache-->>Client: hit from Redis (microseconds latency)
```

      Loading ### Laravel: warm a dictionary from the database

[](#laravel-warm-a-dictionary-from-the-database)

Register the bundled service provider (auto-discovered in Laravel packages) and resolve the service from the container. The provider injects an `IlluminateRedisClient` that wraps `Redis::connection()`.

```
use Alyakin\DictionaryCache\Adapters\PhpRedisClient;
use Alyakin\DictionaryCache\Services\DictionaryCacheService;

$cartCache = app(DictionaryCacheService::class);

$cartCache
    ->setContext("user_{$userId}", 'cart')
    ->setDataProvider(function () use ($userId) {
        return UserCart::whereUserId($userId)
            ->pluck('product_id')
            ->map(fn ($id) => (string) $id)
            ->all();
    })
    ->setTTL(3600);

$cartCache->preload();

if ($cartCache->hasItem((string) $productId)) {
    // product already in cart
}
```

### Plain PHP: manual dictionary without a data provider

[](#plain-php-manual-dictionary-without-a-data-provider)

```
use Alyakin\DictionaryCache\Adapters\PhpRedisClient;
use Alyakin\DictionaryCache\Services\DictionaryCacheService;

$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);

$flagsCache = new DictionaryCacheService(
    redisInstance: new PhpRedisClient($redis)
);

$flagsCache->setContext("tenant_{$tenantId}", 'feature_flags')
    ->setTTL(600)
    ->addItems(['new_checkout', 'promo_banner']);

$enabledFlags = $flagsCache->hasItems(['new_checkout', 'beta_feed']);

if (in_array('new_checkout', $enabledFlags, true)) {
    // enable experiment
}

$flagsCache->keepAlive(); // refresh TTL to keep feature flags hot
```

Methods
-------

[](#methods)

### `__construct`

[](#__construct)

Initializes the service with optional context, data provider, and Redis connection.

**Parameters:**

- `contextId` *(optional, string)*: Unique identifier for the cache.
- `dataProvider` *(optional, Closure)*: Function that returns an array of items to be cached.
- `redisInstance` *(optional, RedisClientInterface|\\Redis|\\RedisCluster)*: Provide your own Redis client or adapter. When omitted inside Laravel, the bundled service provider injects the default connection.

```
use Alyakin\DictionaryCache\Services\DictionaryCacheService;

// $redis is an existing \Redis or compatible connection.

$userCartCache = new DictionaryCacheService(
    contextId: $userId,
    dataProvider: $myDataProviderCallback,
    redisInstance: new PhpRedisClient($redis)
);
```

### `setContext`

[](#setcontext)

Sets the cache key using a context ID and an optional prefix. All class methods use the scope set by this method.

**Parameters:**

- `contextId` *(required, string)*: Unique identifier for the context.
- `key` *(optional, string)*: Prefix for the cache key (default: `dictionary`).

```
$userCartCache->setContext('user_'.$userId, 'cart');
$userFavoriteProductsCache->setContext('user_'.$userId, 'favorite_products');
```

### `setDataProvider`

[](#setdataprovider)

Sets a function that provides data for cache preloading. This method will only be called if the cache has not been initialized yet.

**Parameters:**

- `dataProvider` *(required, Closure)*: Function returning an array of items.

```
$userCartCache->setDataProvider(
    function () use ($userId) {
        return UserCart::whereUserId($userId)->pluck('id')->toArray();
    }
);
```

### `setTTL`

[](#setttl)

Sets the TTL (time-to-live) for the cache key.

**Parameters:**

- `ttl` *(required, int)*: TTL in seconds (must be &gt;= 1).

```
$userCartCache = new DictionaryCacheService();
$userCartCache
    ->setContext('user_'.$userId, 'cart')
    ->setDataProvider(fn () => ['19', '33', '7'])
    ->setTTL(3600 * 24);
```

### `getTTL`

[](#getttl)

Retrieves the TTL of the cache key. If not set, returns default (3600).

### `preload`

[](#preload)

Loads data into the cache using the data provider if it is not initialized. Throws a `RuntimeException` when a data provider was not configured.

### `hasItem`

[](#hasitem)

Checks if a specific item exists in the cache.

**Parameters:**

- `itemId` *(required, string)*: Item to check.

```
$inCart = $userCartCache->hasItem($productId);
return $inCart;
```

### `hasItems`

[](#hasitems)

Checks which items from the list exist in the cache.

**Parameters:**

- `itemIds` *(required, array)*: List of item IDs.

```
$productList = Product::recommendedFor($productId)->get()->pluck('id')->toArray();
$productsInCart = $userCartCache->hasItems($productList);
$recommendations = array_diff($productList, $productsInCart);
return $recommendations;
```

### `getAllItems`

[](#getallitems)

Retrieves all cached items.

### `exists`

[](#exists)

Checks if the cache exists for the scope.

### `addItems`

[](#additems)

Adds multiple items to the cache.

```
public function handle(ProductAddedToCart $event): void {
    $this->cartCache->setContext("user_{$event->userId}", 'cart');
    if ($this->cartCache->exists()) {
        $this->cartCache->addItems([(string) $event->productId]);
    }
}
```

**Parameters:**

- `items` *(required, array)*: Items to add.

### `removeItem`

[](#removeitem)

Removes a specific item from the cache.

**Parameters:**

- `item` *(required, string)*: Item to remove.

```
$this->cartCache->removeItem((string) $event->productId);
```

### `keepAlive`

[](#keepalive)

Refreshes the expiration time of the cache key without modifying TTL.

```
$this->cartCache->removeItem((string) $event->productId)->keepAlive();
```

### `clear`

[](#clear)

Clears the cached data but keeps TTL settings.

Supported Databases
-------------------

[](#supported-databases)

The service works with **Redis-compatible** databases supported by Laravel's Redis driver:

- **Redis** (all versions)
- **KeyDB**
- **Valkey**
- **Dragonfly** (tested with Redis-compatible API)
- **Ardb** (not covered by CI; no maintained public Docker image available)

Requirements
------------

[](#requirements)

- PHP **7.4+**
- Redis-compatible storage
- Laravel **8+** *(optional, only for automatic service provider registration)*

Development
-----------

[](#development)

Install dependencies and run the local toolchain:

```
composer install
composer check # runs lint + phpstan + tests
```

Individual commands:

- `composer lint` – Laravel Pint (`pint --test` in CI).
- `composer stan` – PHPStan level 9.
- `composer test` – PHPUnit (unit + integration; requires a running Redis-compatible server and ext-redis).

GitHub Actions (`.github/workflows/ci.yml`) runs a matrix of PHP 8.1–8.3 against Redis/KeyDB/Valkey/Dragonfly. Ardb is excluded because there is no publicly available Docker image; test it manually if your project relies on it.

Want to Contribute?
-------------------

[](#want-to-contribute)

Read [CONTRIBUTING.md](CONTRIBUTING.md) for setup instructions, coding style, and testing requirements. Please follow the [Code of Conduct](CODE_OF_CONDUCT.md) and report security issues privately via [SECURITY.md](SECURITY.md).

Check out the [open issues](https://github.com/alyakin/dictionary-cache-service/issues) - especially those labeled [good first issue](https://github.com/alyakin/dictionary-cache-service/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)!

Feel free to fork the repo, open a PR, or suggest improvements.

License
-------

[](#license)

This package is open-source and available under the **MIT License**.

###  Health Score

17

—

LowBetter than 6% of packages

Maintenance51

Moderate activity, may be stable

Popularity0

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity12

Early-stage or recently created project

 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.

### Community

Maintainers

![](https://www.gravatar.com/avatar/9eab5787b91f8e98e632f072b3f87a3c5d2f1e4c3a68dbdaaca650e022d0ae61?d=identicon)[2177866](/maintainers/2177866)

---

Top Contributors

[![2177866](https://avatars.githubusercontent.com/u/64738025?v=4)](https://github.com/2177866 "2177866 (8 commits)")

---

Tags

ardbcache-controlcontext-baseddragonflykeydblaravel-packagelaravel-serviceredisvalkey

### Embed Badge

![Health badge](/badges/alyakin-dictionary-cache-service/health.svg)

```
[![Health](https://phpackages.com/badges/alyakin-dictionary-cache-service/health.svg)](https://phpackages.com/packages/alyakin-dictionary-cache-service)
```

###  Alternatives

[predis/predis

A flexible and feature-complete Redis/Valkey client for PHP.

7.8k305.7M2.4k](/packages/predis-predis)[snc/redis-bundle

A Redis bundle for Symfony

1.0k39.4M67](/packages/snc-redis-bundle)[react/cache

Async, Promise-based cache interface for ReactPHP

444112.4M40](/packages/react-cache)[wp-media/wp-rocket

Performance optimization plugin for WordPress

7431.3M3](/packages/wp-media-wp-rocket)[illuminate/cache

The Illuminate Cache package.

12835.6M1.4k](/packages/illuminate-cache)[colinmollenhour/php-redis-session-abstract

A Redis-based session handler with optimistic locking

6325.6M14](/packages/colinmollenhour-php-redis-session-abstract)

PHPackages © 2026

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