PHPackages                             kevinrob/guzzle-cache-middleware - 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. [HTTP &amp; Networking](/categories/http)
4. /
5. kevinrob/guzzle-cache-middleware

ActiveLibrary[HTTP &amp; Networking](/categories/http)

kevinrob/guzzle-cache-middleware
================================

A HTTP/1.1 Cache for Guzzle 6. It's a simple Middleware to be added in the HandlerStack. (RFC 7234)

7.0.0(8mo ago)43417.4M—6.7%79[20 issues](https://github.com/Kevinrob/guzzle-cache-middleware/issues)[2 PRs](https://github.com/Kevinrob/guzzle-cache-middleware/pulls)20MITPHPPHP &gt;=8.1CI failing

Since Jun 30Pushed 2mo ago10 watchersCompare

[ Source](https://github.com/Kevinrob/guzzle-cache-middleware)[ Packagist](https://packagist.org/packages/kevinrob/guzzle-cache-middleware)[ Docs](https://github.com/Kevinrob/guzzle-cache-middleware)[ RSS](/packages/kevinrob-guzzle-cache-middleware/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (11)Versions (65)Used By (20)

guzzle-cache-middleware
=======================

[](#guzzle-cache-middleware)

[![Latest Stable Version](https://camo.githubusercontent.com/6b6b57f3a3c8ac366029641bb7436df4ca1ee8dc8403a1d146f3293689cbabe8/68747470733a2f2f706f7365722e707567782e6f72672f6b6576696e726f622f67757a7a6c652d63616368652d6d6964646c65776172652f762f737461626c65)](https://packagist.org/packages/kevinrob/guzzle-cache-middleware) [![Total Downloads](https://camo.githubusercontent.com/cb02a378d0a74de031939892d243c63ab8d81cbdfad63bdb25d6c297ac596d30/68747470733a2f2f706f7365722e707567782e6f72672f6b6576696e726f622f67757a7a6c652d63616368652d6d6964646c65776172652f646f776e6c6f616473)](https://packagist.org/packages/kevinrob/guzzle-cache-middleware) [![License](https://camo.githubusercontent.com/d902fd2f3f23b02547cf9519ecdeb61ba09b7cd685cc7c8bbbbb7f58326cbf0e/68747470733a2f2f706f7365722e707567782e6f72672f6b6576696e726f622f67757a7a6c652d63616368652d6d6964646c65776172652f6c6963656e7365)](https://packagist.org/packages/kevinrob/guzzle-cache-middleware)[![Tests](https://github.com/Kevinrob/guzzle-cache-middleware/workflows/Tests/badge.svg)](https://github.com/Kevinrob/guzzle-cache-middleware/workflows/Tests/badge.svg)

A HTTP Cache for [Guzzle](https://github.com/guzzle/guzzle) 6+. It's a simple Middleware to be added in the HandlerStack.

Goals
-----

[](#goals)

- RFC 7234 compliance
- Performance and transparency
- Assured compatibility with PSR-7

Built-in storage interfaces
---------------------------

[](#built-in-storage-interfaces)

- [Laravel cache](https://laravel.com/docs/5.2/cache)
- [Flysystem](https://github.com/thephpleague/flysystem)
- [PSR6](https://github.com/php-fig/cache)
- [PSR16](https://github.com/php-fig/simple-cache)
- [WordPress Object Cache](https://codex.wordpress.org/Class_Reference/WP_Object_Cache)

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

[](#installation)

`composer require kevinrob/guzzle-cache-middleware`

or add it the your `composer.json` and run `composer update kevinrob/guzzle-cache-middleware`.

Why?
====

[](#why)

Performance. It's very common to do some HTTP calls to an API for rendering a page and it takes times to do it.

How?
====

[](#how)

With a simple Middleware added at the top of the `HandlerStack` of Guzzle.

```
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use Kevinrob\GuzzleCache\CacheMiddleware;

// Create default HandlerStack
$stack = HandlerStack::create();

// Add this middleware to the top with `push`
$stack->push(new CacheMiddleware(), 'cache');

// Initialize the client with the handler option
$client = new Client(['handler' => $stack]);
```

Examples
========

[](#examples)

Laravel cache
-------------

[](#laravel-cache)

You can use a cache with Laravel, e.g. Redis, Memcache etc.:

```
[...]
use Illuminate\Support\Facades\Cache;
use Kevinrob\GuzzleCache\Strategy\PrivateCacheStrategy;
use Kevinrob\GuzzleCache\Storage\LaravelCacheStorage;

[...]

$stack->push(
  new CacheMiddleware(
    new PrivateCacheStrategy(
      new LaravelCacheStorage(
        Cache::store('redis')
      )
    )
  ),
  'cache'
);
```

Flysystem
---------

[](#flysystem)

```
[...]
use League\Flysystem\Local\LocalFilesystemAdapter;
use Kevinrob\GuzzleCache\Strategy\PrivateCacheStrategy;
use Kevinrob\GuzzleCache\Storage\FlysystemStorage;

[...]

$stack->push(
  new CacheMiddleware(
    new PrivateCacheStrategy(
      new FlysystemStorage(
        new LocalFilesystemAdapter('/path/to/cache')
      )
    )
  ),
  'cache'
);
```

WordPress Object Cache
----------------------

[](#wordpress-object-cache)

```
[...]
use Kevinrob\GuzzleCache\Strategy\PrivateCacheStrategy;
use Kevinrob\GuzzleCache\Storage\WordPressObjectCacheStorage;

[...]

$stack->push(
  new CacheMiddleware(
    new PrivateCacheStrategy(
      new WordPressObjectCacheStorage()
    )
  ),
  'cache'
);
```

Public and shared
-----------------

[](#public-and-shared)

It's possible to add a public shared cache to the stack:

```
[...]
use Cache\Adapter\PHPArray\ArrayCachePool;
use Kevinrob\GuzzleCache\Strategy\PrivateCacheStrategy;
use Kevinrob\GuzzleCache\Strategy\PublicCacheStrategy;
use Kevinrob\GuzzleCache\Storage\Psr6CacheStorage;
use League\Flysystem\Local\LocalFilesystemAdapter;
use Kevinrob\GuzzleCache\Storage\FlysystemStorage;

[...]
// Private caching
$stack->push(
  new CacheMiddleware(
    new PrivateCacheStrategy(
      new FlysystemStorage(
        new LocalFilesystemAdapter('/tmp/')
      )
    )
  ),
  'private-cache'
);

// Public caching
$stack->push(
  new CacheMiddleware(
    new PublicCacheStrategy(
      new Psr6CacheStorage(
        new ArrayCachePool()
      )
    )
  ),
  'shared-cache'
);
```

Greedy caching
--------------

[](#greedy-caching)

In some cases servers might send insufficient or no caching headers at all. Using the greedy caching strategy allows defining an expiry TTL on your own while disregarding any possibly present caching headers:

```
[...]
use Kevinrob\GuzzleCache\KeyValueHttpHeader;
use Kevinrob\GuzzleCache\Strategy\GreedyCacheStrategy;
use Kevinrob\GuzzleCache\Storage\FlysystemStorage;
use League\Flysystem\Local\LocalFilesystemAdapter;

[...]
// Greedy caching
$stack->push(
  new CacheMiddleware(
    new GreedyCacheStrategy(
      new FlysystemStorage(
        new LocalFilesystemAdapter('/tmp/')
      ),
      1800, // the TTL in seconds
      new KeyValueHttpHeader(['Authorization']) // Optional - specify the headers that can change the cache key
    )
  ),
  'greedy-cache'
);
```

Delegate caching
----------------

[](#delegate-caching)

Because your client may call different apps, on different domains, you may need to define which strategy is suitable to your requests.

To solve this, all you have to do is to define a default cache strategy, and override it by implementing your own Request Matchers.

Here's an example:

```
namespace App\RequestMatcher;

use Kevinrob\GuzzleCache\Strategy\Delegate\RequestMatcherInterface;
use Psr\Http\Message\RequestInterface;

class ExampleOrgRequestMatcher implements RequestMatcherInterface
{

    /**
     * @inheritDoc
     */
    public function matches(RequestInterface $request)
    {
        return false !== strpos($request->getUri()->getHost(), 'example.org');
    }
}
```

```
namespace App\RequestMatcher;

use Kevinrob\GuzzleCache\Strategy\Delegate\RequestMatcherInterface;
use Psr\Http\Message\RequestInterface;

class TwitterRequestMatcher implements RequestMatcherInterface
{

    /**
     * @inheritDoc
     */
    public function matches(RequestInterface $request)
    {
        return false !== strpos($request->getUri()->getHost(), 'twitter.com');
    }
}
```

```
require_once __DIR__ . '/vendor/autoload.php';

use App\RequestMatcher\ExampleOrgRequestMatcher;
use App\RequestMatcher\TwitterRequestMatcher;
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use Kevinrob\GuzzleCache\CacheMiddleware;
use Kevinrob\GuzzleCache\Strategy;

$strategy = new Strategy\Delegate\DelegatingCacheStrategy($defaultStrategy = new Strategy\NullCacheStrategy());
$strategy->registerRequestMatcher(new ExampleOrgRequestMatcher(), new Strategy\PublicCacheStrategy());
$strategy->registerRequestMatcher(new TwitterRequestMatcher(), new Strategy\PrivateCacheStrategy());

$stack = HandlerStack::create();
$stack->push(new CacheMiddleware($strategy));
$guzzle = new Client(['handler' => $stack]);
```

With this example:

- All requests to `example.org` will be handled by `PublicCacheStrategy`
- All requests to `twitter.com` will be handled by `PrivateCacheStrategy`
- All other requests won't be cached.

Drupal
------

[](#drupal)

See [Guzzle Cache](https://www.drupal.org/project/guzzle_cache) module.

Links that talk about the project
=================================

[](#links-that-talk-about-the-project)

- [Caching HTTP-Requests with Guzzle 6 and PSR-6](http://a.kabachnik.info/caching-http-requests-with-guzzle-6-and-psr-6.html)

Buy me a coffee
===============

[](#buy-me-a-coffee)

If you like this project, you can [buy me a coffee](https://buymeacoffee.com/kevinrob)! (or a beer 😉)
[![](bmc_qr.png)](https://buymeacoffee.com/kevinrob)

Development
===========

[](#development)

Docker quick start
------------------

[](#docker-quick-start)

### Initialization

[](#initialization)

```
make init
```

### Running test

[](#running-test)

```
make test
```

### Entering container shell

[](#entering-container-shell)

```
make shell
```

###  Health Score

72

—

ExcellentBetter than 100% of packages

Maintenance74

Regular maintenance activity

Popularity69

Solid adoption and visibility

Community47

Growing community involvement

Maturity86

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 77.3% 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 ~68 days

Recently: every ~214 days

Total

58

Last Release

69d ago

Major Versions

v3.5.0 → v4.0.02022-02-07

v4.1.2 → v5.0.02023-11-05

v5.1.0 → 6.0.02024-10-17

6.0.0 → 7.0.02025-09-04

7.0.0 → v8.0.0-RC12026-03-11

PHP version history (4 changes)v0.1PHP &gt;=5.5.0

v4.0.0PHP &gt;=7.2.0

6.0.0PHP &gt;=8.1

v8.0.0-RC1PHP &gt;=8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/7899f7ed00fd6b24ac6328a93aeb2da1f6ffbd477ceba0220226265a68f78f40?d=identicon)[Kevinrob](/maintainers/Kevinrob)

---

Top Contributors

[![Kevinrob](https://avatars.githubusercontent.com/u/4509277?v=4)](https://github.com/Kevinrob "Kevinrob (297 commits)")[![rhysemmerson](https://avatars.githubusercontent.com/u/2549415?v=4)](https://github.com/rhysemmerson "rhysemmerson (10 commits)")[![bpolaszek](https://avatars.githubusercontent.com/u/5569077?v=4)](https://github.com/bpolaszek "bpolaszek (6 commits)")[![scrutinizer-auto-fixer](https://avatars.githubusercontent.com/u/6253494?v=4)](https://github.com/scrutinizer-auto-fixer "scrutinizer-auto-fixer (6 commits)")[![adrian3d](https://avatars.githubusercontent.com/u/3417385?v=4)](https://github.com/adrian3d "adrian3d (5 commits)")[![hannesvdvreken](https://avatars.githubusercontent.com/u/1410358?v=4)](https://github.com/hannesvdvreken "hannesvdvreken (5 commits)")[![Neirda24](https://avatars.githubusercontent.com/u/7036794?v=4)](https://github.com/Neirda24 "Neirda24 (5 commits)")[![peter279k](https://avatars.githubusercontent.com/u/9021747?v=4)](https://github.com/peter279k "peter279k (4 commits)")[![deviantintegral](https://avatars.githubusercontent.com/u/255023?v=4)](https://github.com/deviantintegral "deviantintegral (3 commits)")[![wheelsandcogs](https://avatars.githubusercontent.com/u/1880478?v=4)](https://github.com/wheelsandcogs "wheelsandcogs (3 commits)")[![e-zannelli](https://avatars.githubusercontent.com/u/41945822?v=4)](https://github.com/e-zannelli "e-zannelli (3 commits)")[![gmponos](https://avatars.githubusercontent.com/u/5675248?v=4)](https://github.com/gmponos "gmponos (3 commits)")[![renanbr](https://avatars.githubusercontent.com/u/350222?v=4)](https://github.com/renanbr "renanbr (3 commits)")[![hhamon](https://avatars.githubusercontent.com/u/235550?v=4)](https://github.com/hhamon "hhamon (3 commits)")[![Copilot](https://avatars.githubusercontent.com/in/1143301?v=4)](https://github.com/Copilot "Copilot (3 commits)")[![a3020](https://avatars.githubusercontent.com/u/1431100?v=4)](https://github.com/a3020 "a3020 (2 commits)")[![andrewnicols](https://avatars.githubusercontent.com/u/370047?v=4)](https://github.com/andrewnicols "andrewnicols (2 commits)")[![BenMorel](https://avatars.githubusercontent.com/u/1952838?v=4)](https://github.com/BenMorel "BenMorel (2 commits)")[![bytestream](https://avatars.githubusercontent.com/u/1788397?v=4)](https://github.com/bytestream "bytestream (2 commits)")[![dbclkh](https://avatars.githubusercontent.com/u/21057488?v=4)](https://github.com/dbclkh "dbclkh (2 commits)")

---

Tags

cachedoctrineflysystemguzzlehandlerstackhttplaravel-cachemiddlewareperformancepsr-16psr-6psr-7rfc-7234httpphpmiddlewareFlysystemvalidationpromiseGuzzleperformancepsr7cachepsr6handlerexpirationcache-controlEtagguzzle6http 1.1rfc7234

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/kevinrob-guzzle-cache-middleware/health.svg)

```
[![Health](https://phpackages.com/badges/kevinrob-guzzle-cache-middleware/health.svg)](https://phpackages.com/packages/kevinrob-guzzle-cache-middleware)
```

###  Alternatives

[eljam/guzzle-jwt-middleware

A jwt authentication middleware for guzzle 6

28722.5k3](/packages/eljam-guzzle-jwt-middleware)[rtheunissen/guzzle-rate-limiter

Guzzle 6 middleware used to delay requests dynamically

52177.2k1](/packages/rtheunissen-guzzle-rate-limiter)[rtheunissen/guzzle-log-middleware

Guzzle middleware to log requests and responses

842.3M17](/packages/rtheunissen-guzzle-log-middleware)[graham-campbell/guzzle-factory

Provides A Simple Guzzle Factory With Good Defaults

916.4M49](/packages/graham-campbell-guzzle-factory)[rtheunissen/guzzle-cache-handler

Guzzle 6/7 handler used to cache responses

12142.8k](/packages/rtheunissen-guzzle-cache-handler)[hannesvdvreken/guzzle-debugbar

A Guzzle middleware that logs requests to debugbar's timeline

76410.4k1](/packages/hannesvdvreken-guzzle-debugbar)

PHPackages © 2026

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