flytachi/file-store

File Store library

Maintainers

Package info

github.com/Flytachi/file-store

pkg:composer/flytachi/file-store

Statistics

Installs: 843

Dependents: 2

Suggesters: 0

Stars: 0

Open Issues: 0

v2.0.0 2026-05-13 09:17 UTC

This package is auto-updated.

Last update: 2026-05-13 09:18:11 UTC


README

Latest Version on Packagist Software License

A small, dependency-free key/value file store for PHP — atomic writes, optional TTL, optional HMAC-hashed filenames, and group-shared file permissions for multi-process setups (PHP-FPM + Nginx, queue workers, cron).

Requirements

  • PHP >= 8.3
  • ext-mbstring

Installation

composer require flytachi/file-store

Quick Start

use Flytachi\FileStore\FileStorage;

$store = new FileStorage(
    rootPath:   '/var/app',
    folderName: 'cache/jobs',
);

// Write a value
$store->write('job:42', ['status' => 'queued', 'attempts' => 0]);

// Write with TTL — expires after 1 hour
$store->write('session:abc', $payload, expireAtTimestamp: time() + 3600);

// Read
$job = $store->read('job:42');         // mixed|null

// Check presence (also checks TTL)
if ($store->has('session:abc')) { /* ... */ }

// Delete
$store->del('job:42');

// Enumerate / wipe
$store->keys();     // array of filenames in the store
$store->clear();    // unlink all entries

// Bulk-evict expired entries + crashed-writer tmp files (run from cron)
$store->gc();       // returns count of deleted files

Constructor

new FileStorage(
    string $rootPath,                  // existing, writable directory
    string $folderName,                // subdirectory inside rootPath (created if missing)
    bool   $isHash    = true,          // hash keys → HMAC filenames; off = raw key as filename
    string $hmacType  = 'sha256',      // any hash_hmac() algo
    int    $dirMode   = 0770,          // permissions for the storage directory
    int    $fileMode  = 0660,          // permissions for written files
);

$dirMode / $fileMode are applied after mkdir / file_put_contents via explicit chmod() calls — so the resulting permissions are exactly what you asked for, regardless of the process umask. See docs/03-permissions.md for the full story.

Features at a Glance

Feature How it works
Atomic write Writes go to *.tmp.<random>, then rename() into place. Readers never see a half-written file.
TTL A #^e:<unix-ts>\n prefix line; expired entries are unlinked on first access.
HMAC filenames When isHash=true, the key is run through hash_hmac($hmacType, $key, dirKey) — directory listings reveal no key contents.
Path-traversal guard When isHash=false, raw keys are validated — /, \, \0, ., .., and empty strings are rejected.
Group-writable mode Default 0770/0660 lets PHP-FPM and Nginx (or any two processes in the same group) share the store.
Single dependency Only ext-mbstring for mb_check_encoding / mb_convert_encoding in directory-key normalisation.

When to Use This

  • Job payloads shared between a web process and a worker
  • Per-key caches that need TTL and group-shared writability
  • Lightweight session/blob storage without pulling in Redis/Memcached
  • Any case where SQLite is too heavy and APCu is too local

For high-throughput hot caches or multi-host deployments, reach for something network-aware (Redis, Memcached) — this is a single-host, filesystem-backed store.

Documentation

File Topic
00-overview.md Architecture, file layout, lifecycle of an entry
01-quick-start.md Minimal setup, common patterns
02-api-reference.md Every public method, every parameter
03-permissions.md dirMode / fileMode, umask, multi-user setups
04-concurrency.md Atomic write, locking, race-conditions
05-security.md HMAC hashing, path traversal, unserialize notes
06-exceptions.md FileStorageException — when it's thrown

License

MIT License. See LICENSE.