PHPackages                             redisync/core - 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. [Testing &amp; Quality](/categories/testing)
4. /
5. redisync/core

AbandonedLibrary[Testing &amp; Quality](/categories/testing)

redisync/core
=============

Smart caching middleware for PHP using Redis and MySQL/PostgreSQL

v1.0.1(9mo ago)112MITPHPPHP ^8.1CI passing

Since Aug 10Pushed 3mo agoCompare

[ Source](https://github.com/goktugcy/RediSync)[ Packagist](https://packagist.org/packages/redisync/core)[ Docs](https://github.com/goktugcy/RediSync)[ RSS](/packages/redisync-core/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (11)Versions (13)Used By (0)

RediSync
========

[](#redisync)

High-performance HTTP caching for PHP with Redis storage and optional DB-driven invalidation/write-through (MySQL/PostgreSQL via Doctrine DBAL).

[![Packagist Version](https://camo.githubusercontent.com/6fb9198a25ceacabf076ffdfa291640b874ac980d8fb6ba0939bdd821c6543c5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7265646973796e632f636f72653f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/6fb9198a25ceacabf076ffdfa291640b874ac980d8fb6ba0939bdd821c6543c5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7265646973796e632f636f72653f7374796c653d666c61742d737175617265)[![Total Downloads](https://camo.githubusercontent.com/5d0ac9eb9e41b8fd60def616d68796c16d45c69d78096e91e3b5ac66348f993a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7265646973796e632f636f72653f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/5d0ac9eb9e41b8fd60def616d68796c16d45c69d78096e91e3b5ac66348f993a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7265646973796e632f636f72653f7374796c653d666c61742d737175617265)[![PHP Version](https://camo.githubusercontent.com/c48cd38d1322f26afdc8b878e1bb75b7a8abc7bfe74bc228b3d0c89ebf977192/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f7265646973796e632f636f72653f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/c48cd38d1322f26afdc8b878e1bb75b7a8abc7bfe74bc228b3d0c89ebf977192/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f7265646973796e632f636f72653f7374796c653d666c61742d737175617265)[![License](https://camo.githubusercontent.com/1c3e63b20e15abf7a060566f8e139ae43b8ad9dffd83d7732348cae00ee1a46e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f7265646973796e632f636f72653f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/1c3e63b20e15abf7a060566f8e139ae43b8ad9dffd83d7732348cae00ee1a46e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f7265646973796e632f636f72653f7374796c653d666c61742d737175617265)[![PSR](https://camo.githubusercontent.com/88551361bafd6b3da9080d92b1abe2bc38b6f79fad6e5c369bcfca2e4e22729b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5053522d2d3725324631372d312e78253230253743253230322e782d626c75653f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/88551361bafd6b3da9080d92b1abe2bc38b6f79fad6e5c369bcfca2e4e22729b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5053522d2d3725324631372d312e78253230253743253230322e782d626c75653f7374796c653d666c61742d737175617265)

> Zero-friction HTTP caching for PHP apps: PSR-15 middleware, Redis-backed, DB-aware invalidation.

Quick nav: [Install](#install) · [Configuration](#configuration) · [Middleware](#middleware-usage) · [Facade](#facade-usage) · [Logging](#logging-psr-3) · [Write-through](#write-through-db-to-cache) · [Laravel](#laravel-quickstart) · [CLI](#cli) · [Notes](#notes) · [API contracts](#api-contracts-and-errors) · [Troubleshooting](#troubleshooting-installs-laravelcarbon-and-doctrine-dbal) · [Proof](#proof)

✨ Features
----------

[](#-features)

- PSR-15 middleware: automatic HTTP cache hit/miss flow.
- PSR-7/17 support via nyholm/psr7.
- GET/HEAD-only caching by default, optional bypass with the X-Bypass-Cache header.
- Cache headers: X-RediSync-Cache (HIT/MISS) and Age on hits (PSR-15 and Laravel).
- Conditional requests: automatic ETag generation and If-None-Match → 304.
- Cache-Control aware: respects no-store and private (won't serve/store).
- Vary safety: bypasses cache when Authorization or Cookie exist to avoid leakage.
- Safe caching via status whitelist (default: \[200\]) and Content-Type allow list.
- TTL map by path pattern/regex for per-endpoint TTL control.
- CLI for cache ops: clear-cache, list-keys, key-info, warmup.
- Doctrine DBAL-based DatabaseManager with invalidation hooks.
- Write-through DB helper: update cache immediately after successful DB writes.
- remember() helper: compute-or-cache convenience API (vanilla and Laravel facades).
- PSR-3 logging hooks: cache hit/miss/store, bypass reasons, DB write-through.

🔧 Install
---------

[](#-install)

Add to your project:

```
composer require redisync/core
```

Requirements: PHP 8.1+, Redis (via Predis 1.x or 2.x). Optional: Doctrine DBAL and DB drivers (pdo\_mysql/pdo\_pgsql) if you use DatabaseManager.

⚙️ Configuration
----------------

[](#️-configuration)

Configure programmatically (ENV not required):

```
use RediSync\Cache\CacheManager;

$cache = CacheManager::fromConfig([
  'host' => '127.0.0.1',
  'port' => 6379,
  'database' => 0,
  'prefix' => 'redisync:'
]);
```

DatabaseManager (optional):

```
use RediSync\Database\DatabaseManager;

$db = DatabaseManager::fromDsn('mysql://user:pass@127.0.0.1:3306/app?charset=utf8mb4');

// Cache invalidation after data changes
$db->onInvalidate(function (string $sql, array $params) use ($cache) {
  if (str_starts_with(strtoupper(ltrim($sql)), 'UPDATE USERS')
    || str_starts_with(strtoupper(ltrim($sql)), 'DELETE FROM USERS')
    || str_starts_with(strtoupper(ltrim($sql)), 'INSERT INTO USERS')
  ) {
    $cache->clearByPattern('users:*');
  }
});
```

🧩 Middleware Usage
------------------

[](#-middleware-usage)

```
use Nyholm\Psr7\Factory\Psr17Factory;
use RediSync\Middleware\CacheMiddleware;
use RediSync\Utils\KeyGenerator;

$psr17 = new Psr17Factory();

$middleware = new CacheMiddleware(
  cache: $cache,
  keys: new KeyGenerator('http', ignoredParams: ['nonce', '_ts']),
  ttl: 300,
  responseFactory: $psr17,
  streamFactory: $psr17,
  statusWhitelist: [200],
  allowedContentTypes: ['application/json'],
  ttlMap: [
    '/public/*' => 60,
    '#^/users/\\d+$#' => 300,
  ],
);

// Add it to your PSR-15 stack (Mezzio, Slim, etc.). Middleware caches only GET/HEAD by default.
// Conditional requests: send If-None-Match; 304 is returned when ETag matches (ETag is auto-generated if missing).
// Cache-Control: requests with no-store bypass; responses with no-store/private are not stored.
// Vary safety: Authorization/Cookie on the request bypass the cache to protect user-specific content.
// To force-bypass: send header X-Bypass-Cache: 1. Responses include X-RediSync-Cache: HIT|MISS and Age.
```

### HTTP semantics: ETag, 304, no-store/private, vary

[](#http-semantics-etag-304-no-storeprivate-vary)

- ETag: If the origin response doesn't include ETag, RediSync computes one from the body. Clients sending `If-None-Match` get `304 Not Modified` when it matches.
- no-store/private: A request with `Cache-Control: no-store` bypasses cache. A response with `no-store` or `private` is not stored by RediSync (shared cache).
- Vary safety: Requests carrying `Authorization` or `Cookie` headers bypass cache to avoid leaking personalized content.
- Headers: On cache HITs RediSync adds `X-RediSync-Cache: HIT` and `Age`. On MISS it sets `X-RediSync-Cache: MISS`.

🧩 Facade usage
--------------

[](#-facade-usage)

### Vanilla PHP (framework-agnostic)

[](#vanilla-php-framework-agnostic)

```
use RediSync\Cache\CacheManager;
use RediSync\Facades\RediSync;

$cache = CacheManager::fromConfig(['host' => '127.0.0.1', 'port' => 6379, 'database' => 0, 'prefix' => 'app:']);
RediSync::setInstance($cache);

// get / set
RediSync::set('users:1', ['id' => 1, 'name' => 'Ada'], 300);
$data = RediSync::get('users:1');

// remember (compute-or-cache)
$user = RediSync::remember('users:1', 300, function () {
  // expensive work or DB fetch
  return ['id' => 1, 'name' => 'Ada'];
});

// Evict: set with null deletes the key (by design)
RediSync::set('users:1', null); // equivalent to delete
// Bulk invalidation example
// $cache->clearByPattern('users:*');
```

📜 Logging (PSR-3)
-----------------

[](#-logging-psr-3)

RediSync logs key events with any PSR-3–compatible logger: `cache.hit`, `cache.miss`, `cache.set`, `cache.delete`, `cache.clear_by_pattern`, `httpcache.hit|miss|store|conditional_304|not_cacheable|bypass`, `db.execute`, `db.fetch_*`, `db.write_through.cache_updated`.

Vanilla PHP (Monolog):

```
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use RediSync\Cache\CacheManager;
use RediSync\Facades\RediSync;

$logger = new Logger('app');
$logger->pushHandler(new StreamHandler('php://stdout'));

$cache = CacheManager::fromConfig(['host' => '127.0.0.1', 'port' => 6379]);
$cache->setLogger($logger);
RediSync::setInstance($cache);
RediSync::setLogger($logger); // optional facade shortcut
```

Laravel: LoggerInterface is automatically injected from the container. The ServiceProvider forwards the framework logger to CacheManager and DatabaseManager; no extra setup required.

Write-through DB to Cache
-------------------------

[](#write-through-db-to-cache)

Update cache immediately after a successful DB write (inside a transaction):

```
use RediSync\Database\DatabaseManager;
use RediSync\Cache\CacheManager;

$db = DatabaseManager::fromDsn('sqlite:///:memory:');
// ... create table/users ...

$affected = $db->writeThrough(
  'UPDATE users SET name = :n WHERE id = :id', ['n' => 'alice', 'id' => 1],
  $cache,
  // Build cache entries from the write result
  function (int $affected, array $params, \Doctrine\DBAL\Connection $conn): array {
    if ($affected > 0) {
      return [ ['key' => "users:{$params['id']}", 'value' => ['id' => $params['id'], 'name' => $params['n']], 'ttl' => 300] ];
    }
    return [];
  }
);
```

Shortcut: you can also pass a simple associative array as the plan and use a default TTL:

```
$db->writeThrough(
  'DELETE FROM users WHERE id = :id', ['id' => 1], $cache,
  [ 'users:1' => null ], // set null or use clearByPattern in an onInvalidate callback
  60
);
```

Laravel Quickstart
------------------

[](#laravel-quickstart)

Auto-discovery registers a Service Provider, Facades, and `redisync.cache` middleware.

- Facade (controller) using remember():

```
use RediSync\Bridge\Laravel\Facades\RediSync; // static facade
public function show(int $id) {
  $user = RediSync::remember("users:$id", 300, fn() => \App\Models\User::findOrFail($id)->toArray());
  return response()->json($user);
}
```

- Route cache (GET):

```
use Illuminate\Support\Facades\Route;
Route::middleware('redisync.cache')->get('/api/users/{id}', [UserController::class, 'show']);
```

- HTML cache (view) via RediSyncCache (array/string payloads):

```
use Illuminate\Support\Facades\Auth;
use RediSync\Bridge\Laravel\Facades\RediSyncCache as Cache;
public function getProfile() {
  $u = Auth::user(); if (! $u) return redirect('404');
  $k = "users:profile:{$u->id}"; if ($h = Cache::get($k)) return response($h);
  $h = view('profile', ['user' => $u])->render(); Cache::set($k, $h, 300); return response($h);
}
```

- Data cache (array) via RediSyncCache:

```
use Illuminate\Support\Facades\Auth;
use RediSync\Bridge\Laravel\Facades\RediSyncCache as Cache;
public function getProfileData() {
  $u = Auth::user(); if (! $u) return redirect('404');
  $k = "users:data:{$u->id}"; $d = Cache::get($k) ?: $u->toArray();
  if (! Cache::get($k)) Cache::set($k, $d, 300);
  return view('profile', ['user' => $u]);
}
```

- Invalidation (events):

```
// app/Providers/AppServiceProvider.php
public function boot(\RediSync\Cache\CacheManager $cache): void
{
  \App\Models\User::saved(fn() => $cache->clearByPattern('users:*'));
  \App\Models\User::deleted(fn() => $cache->clearByPattern('users:*'));
}
```

Notes: Uses Laravel Redis config automatically. By default, JSON 200 responses are cached for ~300s. Bypass with header `X-Bypass-Cache: 1`.

HTTP semantics in Laravel middleware:

- GET/HEAD cache with `X-RediSync-Cache` (HIT/MISS) and `Age` on hits.
- `If-None-Match` supported; returns `304 Not Modified` when matching the stored ETag (computed if absent).
- Respects `Cache-Control: no-store` on requests and `no-store`/`private` on responses (won't store).
- Requests containing `Authorization` or cookies bypass the cache for safety.

### Write-through in Laravel

[](#write-through-in-laravel)

```
// In a service or controller where you have the DB connection DSN
use RediSync\Bridge\Laravel\Facades\RediSyncCache as Cache;
use RediSync\Database\DatabaseManager;

$db = DatabaseManager::fromDsn(env('DATABASE_URL'));
$db->writeThrough(
  'INSERT INTO posts (title) VALUES (:t)', ['t' => $title],
  app(\RediSync\Cache\CacheManager::class),
  fn(int $affected, array $p, \Doctrine\DBAL\Connection $c) => $affected
    ? [ ['key' => 'posts:latest', 'value' => /* recompute */ [], 'ttl' => 120] ]
    : []
);
```

🛠️ CLI
------

[](#️-cli)

Use the bundled CLI for quick cache operations. The tool reads Redis config from `config/config.php`.

```
vendor/bin/redisync help
```

Commands:

- clear-cache \[pattern\]
    - Delete keys by pattern (default: `*`).
    - Example: `vendor/bin/redisync clear-cache users:*`
- list-keys \[pattern\] \[limit\]
    - List keys (default pattern `*`, limit `100`).
    - Example: `vendor/bin/redisync list-keys api:* 50`
- key-info
    - Show TTL/type/size/exists.
    - Example: `vendor/bin/redisync key-info users:1`
- warmup \[ttl\]
    - Read keys from STDIN and set placeholder values with TTL (default 60).
    - Example:

```
printf "a\nb\n" | vendor/bin/redisync warmup 30
```

📷 Proof
-------

[](#-proof)

[![RediSync usage proof](https://camo.githubusercontent.com/f624e02e483cb875287e04c9c5f18bcc72651020b5e1a8e76179ee944266b540/68747470733a2f2f726666757265656a716a7a7262717a72637978762e73757061626173652e636f2f73746f726167652f76312f6f626a6563742f7075626c69632f696d616765732f7265646973796e632e706e67)](https://camo.githubusercontent.com/f624e02e483cb875287e04c9c5f18bcc72651020b5e1a8e76179ee944266b540/68747470733a2f2f726666757265656a716a7a7262717a72637978762e73757061626173652e636f2f73746f726167652f76312f6f626a6563742f7075626c69632f696d616765732f7265646973796e632e706e67)

📝 Notes
-------

[](#-notes)

- Middleware caches only GET/HEAD requests by default.
- Use status whitelist and Content-Type filters for safe caching.
- TTL map allows per-path TTL control.

### API contracts and errors

[](#api-contracts-and-errors)

- Cache null semantics: `set($key, null)` evicts the key to avoid ambiguity with `get()` returning null.
- Exceptions: Redis/DB errors currently bubble up from underlying libraries. There’s no wrapper exception layer in 1.x; handle with try/catch in your app as needed.

Troubleshooting installs (Laravel/Carbon and Doctrine DBAL)
-----------------------------------------------------------

[](#troubleshooting-installs-laravelcarbon-and-doctrine-dbal)

If your app uses Laravel 11 + Carbon 3, you may see a conflict involving `doctrine/dbal` and `carbonphp/carbon-doctrine-types` when installing `redisync/core`.

What changed: RediSync no longer hard-requires `doctrine/dbal`. It's optional and only needed if you plan to use `DatabaseManager`.

- Install RediSync first:

    ```
    composer require redisync/core
    ```
- If you need DB features, require a DBAL version compatible with your stack. For example:

    ```
    composer require doctrine/dbal:^3.8
    ```

If Composer still reports conflicts, align DBAL with the versions compatible with your Laravel/Carbon lock (check `composer why doctrine/dbal` and `composer why-not doctrine/dbal:^3.10`).

###  Health Score

37

—

LowBetter than 83% of packages

Maintenance72

Regular maintenance activity

Popularity7

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity52

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

12

Last Release

278d ago

Major Versions

v0.1.9 → v1.0.02025-08-13

### Community

Maintainers

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

---

Top Contributors

[![goktugcy](https://avatars.githubusercontent.com/u/17319750?v=4)](https://github.com/goktugcy "goktugcy (40 commits)")

---

Tags

cachelaravellaravel-packagemysqlphpphp8phpunitpostgreredisredis-cachepsr-7middlewaredoctrinedbalrediscachepsr-15

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/redisync-core/health.svg)

```
[![Health](https://phpackages.com/badges/redisync-core/health.svg)](https://phpackages.com/packages/redisync-core)
```

###  Alternatives

[cakephp/cakephp

The CakePHP framework

8.8k18.5M1.6k](/packages/cakephp-cakephp)[chubbyphp/chubbyphp-framework

A minimal, highly performant middleware PSR-15 microframework built with as little complexity as possible, aimed primarily at those developers who want to understand all the vendors they use.

13544.4k4](/packages/chubbyphp-chubbyphp-framework)[yiisoft/yii-middleware

Yii Middleware

21151.3k1](/packages/yiisoft-yii-middleware)[phpro/http-tools

HTTP tools for developing more consistent HTTP implementations.

28137.8k](/packages/phpro-http-tools)[mezzio/mezzio-authentication-oauth2

OAuth2 (server) authentication middleware for Mezzio and PSR-7 applications.

28483.0k2](/packages/mezzio-mezzio-authentication-oauth2)[mezzio/mezzio-authentication

Authentication middleware for Mezzio and PSR-7 applications

121.6M26](/packages/mezzio-mezzio-authentication)

PHPackages © 2026

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