PHPackages                             scafera/file - 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. [File &amp; Storage](/categories/file-storage)
4. /
5. scafera/file

ActiveSymfony-bundle[File &amp; Storage](/categories/file-storage)

scafera/file
============

File handling for the Scafera framework

v1.0.1(1mo ago)06MITPHPPHP &gt;=8.4

Since Apr 14Pushed 1mo agoCompare

[ Source](https://github.com/scafera/file)[ Packagist](https://packagist.org/packages/scafera/file)[ Docs](https://github.com/scafera/file)[ RSS](/packages/scafera-file/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (2)Dependencies (4)Versions (3)Used By (0)

scafera/file
============

[](#scaferafile)

File handling for the Scafera framework. Upload, validate, store, and serve files — all behind Scafera-owned types.

Internally adopts `symfony/http-foundation` Upload, `symfony/mime`, and `symfony/filesystem`. Userland code never imports Symfony file types — boundary enforcement blocks it at compile time.

> **Provides:** File handling for Scafera — upload (`UploadExtractor` → `UploadedFile`), validate (`UploadValidator` + `UploadConstraint`), store (`FileStorage`), and serve (`FileResponse`) behind Scafera-owned types. Server-side MIME detection via magic bytes, automatic path-traversal sanitization, and collision-safe filenames.
>
> **Depends on:** A Scafera host project whose architecture package defines a storage directory via `getStorageDir()` (e.g. `var/uploads/` in `scafera/layered`).
>
> **Extension points:** None of its own — the package exposes concrete services (`UploadExtractor`, `UploadValidator`, `FileStorage`, `FileResponse`) used directly. `UploadConstraint` is configured per-call with allowed extensions, MIME types, and max size.
>
> **Not responsible for:** Form processing (compose with `scafera/form` per ADR-062) · client-supplied MIME types (server-side magic bytes only) · choosing the storage directory (architecture package owns `getStorageDir()`) · direct use of Symfony file types in userland (blocked by `FileBoundaryPass` and `FileBoundaryValidator`).

This is a **capability package**. It adds optional file handling to a Scafera project. It does not define folder structure or architectural rules — those belong to architecture packages.

What it provides
----------------

[](#what-it-provides)

- `UploadedFile` — file metadata (name, extension, MIME, size) with server-side MIME detection
- `UploadExtractor` — extract uploads from requests
- `UploadConstraint` + `UploadValidator` — validate files (extension, MIME, size)
- `FileStorage` — store files with path traversal protection and collision handling
- `FileResponse` — serve files as download or inline

Design decisions
----------------

[](#design-decisions)

- **MIME detection is server-side** — uses `symfony/mime` magic bytes, not the client-supplied Content-Type header. Prevents spoofed file types.
- **Path traversal is structurally prevented** — directory segments are sanitized (stripped of `..` and `.`) before any filesystem operation. No file is ever written before validation.
- **File collision handling** — if a file with the same name exists, a unique random suffix is appended automatically. No silent overwrite.
- **Storage path is architecture-owned** — the storage directory is defined by `getStorageDir()` on the architecture package, not hardcoded. For `scafera/layered`, this is `var/uploads/`.
- **Form and file are separate capabilities** — file uploads are not handled by `scafera/form`. Controllers compose both packages explicitly (ADR-062).

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

[](#installation)

```
composer require scafera/file
```

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

[](#requirements)

- PHP &gt;= 8.4
- scafera/kernel

Upload and validate
-------------------

[](#upload-and-validate)

```
use Scafera\File\UploadExtractor;
use Scafera\File\UploadValidator;
use Scafera\File\UploadConstraint;

$file = $uploads->get($request, 'avatar');

if ($file !== null) {
    $result = $validator->validate($file, new UploadConstraint(
        allowedExtensions: ['jpg', 'png'],
        allowedMimeTypes: ['image/jpeg', 'image/png'],
        maxSizeBytes: 2_097_152,  // 2 MB
    ));

    if (!$result->isValid()) {
        // $result->error() — human-readable message
    }
}
```

MIME detection uses `symfony/mime` magic bytes — not the client-supplied MIME type.

Store
-----

[](#store)

```
use Scafera\File\FileStorage;

$path = $storage->store($file, 'avatars');           // 'avatars/photo.jpg'
$path = $storage->store($file, 'avatars', 'me.jpg'); // 'avatars/me.jpg'

$storage->exists($path);   // true
$storage->delete($path);   // true
```

The storage directory is defined by the architecture package via `getStorageDir()`. For `scafera/layered`, this is `var/uploads/`. Filenames are sanitized (directory components stripped). If a file with the same name already exists, a unique suffix is appended automatically.

Path traversal is structurally prevented — directory segments are sanitized before any filesystem operation.

Serve files
-----------

[](#serve-files)

```
use Scafera\File\FileResponse;

return FileResponse::download($path, 'report.pdf');
return FileResponse::inline($path);
```

`FileResponse` does not implement `ResponseInterface`. A dedicated listener converts it to a binary response at priority 10 (before the kernel's response listener).

File uploads in forms
---------------------

[](#file-uploads-in-forms)

File uploads are **not** handled by `scafera/form`. Use both packages together in your controller (ADR-062):

```
$form = $this->formHandler->handle($request, ProfileInput::class);
$avatar = $this->uploads->get($request, 'avatar');
```

Two explicit calls. Form handles POST data, file handles uploads. Each validates independently.

Boundary enforcement
--------------------

[](#boundary-enforcement)

BlockedUse instead`Symfony\Component\HttpFoundation\File\UploadedFile``Scafera\File\UploadedFile``Symfony\Component\HttpFoundation\File\File``Scafera\File\FileStorage``Symfony\Component\Filesystem\*``Scafera\File\FileStorage`Enforced via compiler pass (build time) and validator (`scafera validate`). Detects `use`, `new`, and `extends` patterns.

License
-------

[](#license)

MIT

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance89

Actively maintained with recent releases

Popularity4

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

Total

2

Last Release

54d ago

### Community

Maintainers

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

---

Top Contributors

[![samaphp](https://avatars.githubusercontent.com/u/531627?v=4)](https://github.com/samaphp "samaphp (3 commits)")

---

Tags

phpfilestoragescafera

###  Code Quality

TestsPHPUnit

### Embed Badge

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

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

###  Alternatives

[aws/aws-sdk-php

AWS SDK for PHP - Use Amazon Web Services in your PHP project

6.3k532.1M2.5k](/packages/aws-aws-sdk-php)[drupal/core

Drupal is an open source content management platform powering millions of websites and applications.

21764.8M1.6k](/packages/drupal-core)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.4M195](/packages/sulu-sulu)[drupal/core-recommended

Locked core dependencies; require this project INSTEAD OF drupal/core.

6941.5M395](/packages/drupal-core-recommended)[bitrix24/b24phpsdk

An official PHP library for the Bitrix24 REST API

10139.4k5](/packages/bitrix24-b24phpsdk)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

585.4M506](/packages/shopware-core)

PHPackages © 2026

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