PHPackages                             stadly/file-waiter - 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. stadly/file-waiter

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

stadly/file-waiter
==================

File serving made easy. A PHP library for serving files from any file system over HTTP, with support for conditional and ranged requests.

v1.1.0(2y ago)3294↓100%2MITPHPPHP &gt;=8.0

Since Sep 10Pushed 2y ago1 watchersCompare

[ Source](https://github.com/Stadly/FileWaiter)[ Packagist](https://packagist.org/packages/stadly/file-waiter)[ Docs](https://github.com/Stadly/FileWaiter)[ RSS](/packages/stadly-file-waiter/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (5)Dependencies (15)Versions (6)Used By (2)

FileWaiter
==========

[](#filewaiter)

[![Latest Version on Packagist](https://camo.githubusercontent.com/4c77cc7567dab48cadb2171fb0c6e6fabb438762ce26efcc90187ba7ee26762f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f737461646c792f66696c652d7761697465722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/stadly/file-waiter)[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE.md)[![Coverage Status](https://camo.githubusercontent.com/6438a97728f164bfc467aeac0da08efdd2e199f2bbdab6c70841ef0f36918be2/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f636f7665726167652f672f537461646c792f46696c655761697465722e7376673f7374796c653d666c61742d737175617265)](https://scrutinizer-ci.com/g/Stadly/FileWaiter/code-structure)[![Quality Score](https://camo.githubusercontent.com/43771bd1b2c2a71e5c7faa1edf35c0e0b0a045d20f7f510462f71b2aa3c40105/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f672f537461646c792f46696c655761697465722e7376673f7374796c653d666c61742d737175617265)](https://scrutinizer-ci.com/g/Stadly/FileWaiter)[![Total Downloads](https://camo.githubusercontent.com/3a6999dd637ce79434f145994efe4d99eab9da60207603cdda64ee0bfe70a22c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f737461646c792f66696c652d7761697465722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/stadly/file-waiter)

File serving made easy. A PHP library for serving files from any file system over HTTP, with support for conditional and ranged requests.

Install
-------

[](#install)

Via Composer

```
$ composer require stadly/file-waiter
```

Usage
-----

[](#usage)

```
use Stadly\FileWaiter\Adapter\Local;
use Stadly\FileWaiter\File;
use Stadly\FileWaiter\Waiter;

$streamFactory = new \GuzzleHttp\Psr7\HttpFactory();                // Any PSR-17 compatible stream factory.
$file = new File(new Local('filename.txt', $streamFactory));        // Or another file adapter. See below.
$responseFactory = new \GuzzleHttp\Psr7\HttpFactory();              // Any PSR-17 compatible response factory.

$waiter = new Waiter($file, $responseFactory);

$request = \GuzzleHttp\Psr7\ServerRequest::fromGlobals();           // Any PSR-7 compatible server request.

$response = $waiter->handle($request);                              // The response is created by the response factory.

$emitter = new \Laminas\HttpHandlerRunner\Emitter\SapiEmitter();    // Any way of emitting PSR-7 responses.
$emitter->emit($response);
die();
```

### Conditional requests

[](#conditional-requests)

`FileWaiter` automatically handles conditional requests by looking at the the headers `If-Match`, `If-None-Match`, `If-Modified-Since`, `If-Unmodified-Since`, and `If-Range`.

```
$request = new \GuzzleHttp\Psr7\ServerRequest('GET', '');           // Any PSR-7 compatible server request.
$request = $request->withHeader('If-None-Match', '"foo"');

$response = $waiter->handle($request);                              // 304 Not Modified if the file's entity tag is "foo".
```

### Ranged requests

[](#ranged-requests)

`FileWaiter` automatically handles ranged requests by looking at the header `Range`.

```
$request = new \GuzzleHttp\Psr7\ServerRequest('GET', '');           // Any PSR-7 compatible server request.
$request = $request->withHeader('Range', 'bytes=10-20');

$response = $waiter->handle($request);                              // Response contains only the requested bytes.
```

### File adapters

[](#file-adapters)

By using file adapters, `FileWaiter` can serve files from any file system. `FileWaiter` comes bundled with an adapter for serving files from the local file system. Other adapters can be installed separately. Here is a list of currently available adapters:

- `Local`: For serving files stored in the local file system.
- [`ByteString`](https://github.com/Stadly/FileWaiter-ByteString): For serving files stored in a string.
- [`Flysystem`](https://github.com/Stadly/FileWaiter-Flysystem): For serving files stored in [Flysystem](https://flysystem.thephpleague.com/v2/docs/).

Additional file adapters can easily be created by implementing `Stadly\FileWaiter\Adapter`. By using one of the available adapters for [Flysystem](https://flysystem.thephpleague.com/v2/docs/), most needs should already be covered.

Most times, information about the file, such as file name, file size, media type, last modified date, and entity tag is provided by the file adapter. There are, however, times when is not desired (for instance, if you have already stored the media type or a custom entity tag in a database) or possible (for instance, the [`ByteString`](https://github.com/Stadly/FileWaiter-ByteString) adapter cannot provide file name and last modified date). In such cases, you can overwrite the file information populated by the file adapter. You can also specify which information should be populated by the file adapter to prevent popultating unncecessary information that may be costly to retrieve.

```
use Stadly\FileWaiter\File;
use Stadly\FileWaiter\Adapter\Local;
use Stadly\Http\Header\Value\EntityTag\EntityTag;

$populateInfo = File::ALL_INFO ^ File::ENTITY_TAG;                  // Do not populate entity tag.
$file = new File(new Local('filename.txt', $streamFactory), $populateInfo);
$file->setEntityTag(new EntityTag('foo'));                          // Set custom entity tag.
```

Change log
----------

[](#change-log)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Testing
-------

[](#testing)

```
$ composer test
```

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) and [CODE\_OF\_CONDUCT](CODE_OF_CONDUCT.md) for details.

Security
--------

[](#security)

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

Credits
-------

[](#credits)

- [Magnar Ovedal Myrtveit](https://github.com/Stadly)
- [All Contributors](https://github.com/Stadly/FileWaiter/contributors)

License
-------

[](#license)

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

###  Health Score

29

—

LowBetter than 60% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity16

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity59

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 ~185 days

Total

5

Last Release

960d ago

Major Versions

v0.2.0 → v1.0.02021-09-10

PHP version history (2 changes)v0.1.0PHP &gt;=7.4

v1.1.0PHP &gt;=8.0

### Community

Maintainers

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

---

Top Contributors

[![Stadly](https://avatars.githubusercontent.com/u/7263579?v=4)](https://github.com/Stadly "Stadly (30 commits)")

---

Tags

httpphpfile serverStadlyconditional requestfile servingranged request

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/stadly-file-waiter/health.svg)

```
[![Health](https://phpackages.com/badges/stadly-file-waiter/health.svg)](https://phpackages.com/packages/stadly-file-waiter)
```

###  Alternatives

[guzzlehttp/psr7

PSR-7 message implementation that also provides common utility methods

8.0k1.0B3.1k](/packages/guzzlehttp-psr7)[laudis/neo4j-php-client

Neo4j-PHP-Client is the most advanced PHP Client for Neo4j

184616.9k31](/packages/laudis-neo4j-php-client)[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)[openswoole/core

Openswoole core library

181.1M31](/packages/openswoole-core)[simpod/clickhouse-client

PHP ClickHouse Client

19116.7k](/packages/simpod-clickhouse-client)

PHPackages © 2026

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