PHPackages                             middlewares/filesystem - 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. middlewares/filesystem

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

middlewares/filesystem
======================

Middleware to save or read responses using Flysystem

v3.0.0(12mo ago)926.0k—0%1MITPHPPHP ^7.2 || ^8.0CI passing

Since Oct 2Pushed 11mo ago1 watchersCompare

[ Source](https://github.com/middlewares/filesystem)[ Packagist](https://packagist.org/packages/middlewares/filesystem)[ Docs](https://github.com/middlewares/filesystem)[ RSS](/packages/middlewares-filesystem/feed)WikiDiscussions master Synced today

READMEChangelog (10)Dependencies (9)Versions (13)Used By (0)

middlewares/filesystem
======================

[](#middlewaresfilesystem)

[![Latest Version on Packagist](https://camo.githubusercontent.com/9cb960429214f9c8c35ebcaf4abf5c9d900757aa87e9deffa2dfbe20044890ab/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d6964646c6577617265732f66696c6573797374656d2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/middlewares/filesystem)[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE)[![Testing](https://github.com/middlewares/filesystem/workflows/testing/badge.svg)](https://github.com/middlewares/filesystem/workflows/testing/badge.svg)[![Total Downloads](https://camo.githubusercontent.com/b07771005b653068f1588e901357ec5e02eb610c1abdf025df99e272c2520928/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6d6964646c6577617265732f66696c6573797374656d2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/middlewares/filesystem)

Middleware to save or read responses from files. It uses [Flysystem](http://flysystem.thephpleague.com/) as filesystem handler, so you can not only use a local directories, but also any other adapter like [ftp](http://flysystem.thephpleague.com/adapter/ftp/), [sftp](http://flysystem.thephpleague.com/adapter/sftp/), [dropbox](http://flysystem.thephpleague.com/adapter/dropbox/), etc... This package includes the following components:

- [Reader](#reader)
- [Writer](#writer)

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

[](#requirements)

- PHP &gt;= 7.2
- A [PSR-7 http library](https://github.com/middlewares/awesome-psr15-middlewares#psr-7-implementations)
- A [PSR-15 middleware dispatcher](https://github.com/middlewares/awesome-psr15-middlewares#dispatcher)

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

[](#installation)

This package is installable and autoloadable via Composer as [middlewares/filesystem](https://packagist.org/packages/middlewares/filesystem).

```
composer require middlewares/filesystem
```

Example
-------

[](#example)

```
Dispatcher::run([
    Middlewares\Reader::createFromDirectory(__DIR__.'/assets')
]);
```

Reader
------

[](#reader)

To read the response body from a file under the following conditions:

- Only `GET` methods are allowed, returning a `405` code otherwise.
- If the request path has no extension, assume it's a directory and append `/index.html`. For example: if the request path is `/post/23`, the file used is `/post/23/index.html`.
- It can handle gzipped files. For example, if `/post/23/index.html` does not exists but `/post/23/index.html.gz` is available and the request header `Accept-Encoding` contains `gzip`, returns it.
- `Accept-Ranges` is also supported, useful to server big files like videos.

Example using a ftp storage:

```
use League\Flysystem\Filesystem;
use League\Flysystem\Ftp\FtpAdapter;
use League\Flysystem\Ftp\FtpConnectionOptions;

$adapter = new League\Flysystem\Ftp\FtpAdapter(
    FtpConnectionOptions::fromArray([
        'host' => 'hostname',
        'root' => '/root/path/',
        'username' => 'username',
        'password' => 'password',
        'port' => 21,
        'ssl' => false,
        'timeout' => 90,
        'utf8' => false,
        'passive' => true,
        'transferMode' => FTP_BINARY,
        'systemType' => null, // 'windows' or 'unix'
        'ignorePassiveAddress' => null, // true or false
        'timestampsOnUnixListingsEnabled' => false, // true or false
        'recurseManually' => true // true
    ])
);

// The FilesystemOperator
$filesystem = new Filesystem($adapter);

Dispatcher::run([
    new Middlewares\Reader($filesystem)
]);
```

Optionally, you can provide a `Psr\Http\Message\ResponseFactoryInterface` and `Psr\Http\Message\StreamFactoryInterface`, that will be used to create the response and stream. If they are not not defined, [Middleware\\Utils\\Factory](https://github.com/middlewares/utils#factory) will be used to detect them automatically.

```
$responseFactory = new MyOwnResponseFactory();
$streamFactory = new MyOwnStreamFactory();

$reader = new Middlewares\Reader($filesystem, $responseFactory, $streamFactory);
```

### continueOnError

[](#continueonerror)

Allows to continue to the next middleware on error (file not found, method not allowed, etc). This allows to create a simple caching system as the following:

```
$cache = new Filesystem(new LocalFilesystemAdapter(__DIR__.'/path/to/files'));

Dispatcher::run([
    (new Middlewares\Reader($cache))    //read and returns the cached response...
        ->continueOnError(),            //...but continue if the file does not exists

    new Middlewares\Writer($cache),     //save the response in the cache

    new Middlewares\AuraRouter($route), //create a response using, for example, Aura.Router
]);
```

Writer
------

[](#writer)

Saves the response content into a file if all of the following conditions are met:

- The method is `GET`
- The status code is `200`
- The `Cache-Control` header does not contain `no-cache` and `no-store`

To be compatible with `Reader` behaviour:

- If the request path has no extension, assume it's a directory and append `/index.html`. For example: if the request path is `/post/23`, the file saved is `/post/23/index.html`.
- If the response is gzipped (has the header `Content-Encoding: gzip`) the file is saved with the extension .gz. For example `/post/23/index.html.gz` (instead `/post/23/index.html`).

```
$filesystem = new Filesystem(new LocalFilesystemAdapter(__DIR__.'/storage'));

Dispatcher::run([
    new Middlewares\Writer($filesystem)
]);
```

Optionally, you can provide a `Psr\Http\Message\StreamFactoryInterface` as the second that will be used to create a new body to the response. If it's not defined, [Middleware\\Utils\\Factory](https://github.com/middlewares/utils#factory) will be used to detect it automatically.

```
$streamFactory = new MyOwnStreamFactory();

$reader = new Middlewares\Writer($filesystem, $streamFactory);
```

Helpers
-------

[](#helpers)

### createFromDirectory

[](#createfromdirectory)

Both `Reader` and `Writer` have a static method as a shortcut to create instances using a directory in the local filesystem, due this is the most common case:

```
Dispatcher::run([
    Middlewares\Writer::createFromDirectory(__DIR__.'/assets')
    Middlewares\Reader::createFromDirectory(__DIR__.'/assets')
]);
```

---

Please see [CHANGELOG](CHANGELOG.md) for more information about recent changes and [CONTRIBUTING](CONTRIBUTING.md) for contributing details.

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

###  Health Score

47

—

FairBetter than 94% of packages

Maintenance51

Moderate activity, may be stable

Popularity33

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity75

Established project with proven stability

 Bus Factor1

Top contributor holds 94.6% 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 ~281 days

Recently: every ~653 days

Total

12

Last Release

363d ago

Major Versions

v0.5.0 → v1.0.02018-01-25

v1.1.0 → v2.0.02019-11-30

v2.0.1 → v3.0.02025-03-23

PHP version history (4 changes)v0.1.0PHP ^5.6 || ^7.0

v0.5.0PHP ^7.0

v2.0.0PHP ^7.2

v2.0.1PHP ^7.2 || ^8.0

### Community

Maintainers

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

![](https://www.gravatar.com/avatar/42e0d72f42eb7d84f67e20d28606da42e5a3248ca908b1eadb4366aafeae2561?d=identicon)[filisko](/maintainers/filisko)

---

Top Contributors

[![oscarotero](https://avatars.githubusercontent.com/u/377873?v=4)](https://github.com/oscarotero "oscarotero (53 commits)")[![filisko](https://avatars.githubusercontent.com/u/8798694?v=4)](https://github.com/filisko "filisko (3 commits)")

---

Tags

cachefilesystemflysystemhttpmiddlewarepsr-15httppsr-7middlewarefilesystemFlysystemcachepsr-15

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/middlewares-filesystem/health.svg)

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

###  Alternatives

[middlewares/request-handler

Middleware to execute request handlers

451.5M23](/packages/middlewares-request-handler)[middlewares/fast-route

Middleware to use FastRoute

96189.1k14](/packages/middlewares-fast-route)[middlewares/negotiation

Middleware to implement content negotiation

47437.6k11](/packages/middlewares-negotiation)[middlewares/trailing-slash

Middleware to normalize the trailing slash of the uri path

32495.2k10](/packages/middlewares-trailing-slash)[middlewares/payload

Middleware to parse the body of the request with support for json, csv and url-encode

32464.9k16](/packages/middlewares-payload)[middlewares/http-authentication

Middleware to implement Basic and Digest Http authentication

35300.9k2](/packages/middlewares-http-authentication)

PHPackages © 2026

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