amphp/file
Non-blocking file I/O for PHP 8.1+ in the AMPHP ecosystem. Read/write files or stream via async file handles while keeping apps responsive. Uses multi-process by default, with optional eio/uv/parallel drivers when available.
file_get_contents(), fopen(), etc., with non-blocking alternatives, critical for high-concurrency Laravel apps (e.g., API gateways, background jobs).BlockingFilesystemDriver, ParallelFilesystemDriver, UvFilesystemDriver), allowing TPMs to optimize for:
BlockingFilesystemDriver (fallback).ext-uv/ext-eio (low-latency, multi-process).ext-parallel (shared-memory efficiency).Filesystem::driver('amp')), replacing Illuminate\Filesystem\FilesystemAdapter.Filesystem facade with async methods (e.g., Filesystem::asyncRead(), Filesystem::asyncPut()), leveraging Laravel’s FilesystemManager for driver switching.| Risk Area | Mitigation Strategy |
|---|---|
| Fiber/Async Learning Curve | Provide adapters to wrap async methods in sync-like interfaces (e.g., syncRead()). |
| Driver Dependency | Default to BlockingFilesystemDriver for compatibility; require ext-uv/ext-eio for performance. |
| Laravel Ecosystem Gaps | Extend Illuminate\Filesystem\Filesystem to delegate to amphp/file where possible. |
| Locking Complexity | Use KeyedFileMutex for distributed locks (e.g., in Laravel Forge/Envoyer deployments). |
| PHP 8.1+ Requirement | Enforce in composer.json; use Laravel Breeze/Pint for migration. |
Concurrency Model:
amphp/file replace all filesystem operations in Laravel, or only high-I/O paths (e.g., uploads, logs)?Driver Strategy:
BlockingFilesystemDriver or require explicit opt-in for async drivers?Error Handling:
PendingOperationError (e.g., from ext-uv) into Laravel’s exception stack?FilesystemException wrapper.Testing:
Amp\Loop::run() in tests or mock the driver.Deployment:
ext-uv, ext-eio) are required for production, and how to validate their presence?php artisan vendor:publish --provider="Amp\File\ServiceProvider").Illuminate\Filesystem\Filesystem with a decorator pattern to delegate async calls to amphp/file.FilesystemManager to support amp driver.Amp\File\FileCache for job payload storage (e.g., large file processing).Storage::put() with async variants in queue jobs.amphp/file.KeyedFileMutex for safe deployments (e.g., lock config files during updates).| Phase | Action | Tools/Examples |
|---|---|---|
| Assessment | Audit filesystem usage (e.g., file_get_contents, Storage::disk() calls). |
phpstan, laravel-debugbar |
| Adapter Layer | Create a SyncFilesystem facade wrapping amphp/file sync methods. |
Filesystem::syncRead(), Filesystem::syncPut() |
| Opt-In Testing | Enable async driver in config/filesystems.php for specific disks. |
php<br>// config/filesystems.php<br>'disks' => [<br> 'local_amp' => [<br> 'driver' => 'amp',<br> 'root' => storage_path('app'),<br> ],<br>],<br> |
| Performance Tuning | Benchmark BlockingFilesystemDriver vs. UvFilesystemDriver for critical paths. |
laravel-debugbar, blackfire.io |
| Full Replacement | Deprecate sync methods in favor of async (Laravel 11+). | Deprecation warnings in Illuminate\Filesystem. |
Illuminate\Contracts\Filesystem\Filesystem for amphp/file to drop-in replace.class AmpFilesystem implements Filesystem {
public function read($path) {
return Amp\File\read(storage_path($path));
}
// ... other methods
}
Illuminate\Filesystem\FilesystemAdapter to support async drivers.class AmpFilesystemAdapter extends FilesystemAdapter {
protected function readStream($path) {
return Amp\File\openFile($this->path($path), 'r');
}
}
PhpSpreadsheet file I/O with async variants.amphp/file for thumbnail generation.// Before
$contents = Storage::disk('local')->get('large-file.zip');
// After
$contents = Amp\File\read(storage_path('app/large-file.zip'));
Filesystem::sync() vs. Filesystem::async()).config/caching.php file writes) to async.amphp/file to a specific minor version (e.g., ^4.0) to avoid breaking changes.config/filesystems.php:
'drivers' => [
'amp' => [
'driver' => AmpFilesystemDriver::class,
'options' => [
'default' => env('FILESYSTEM_DRIVER', 'uv'), // 'blocking', 'uv', 'eio'
],
],
],
Amp\File\read() latency).Amp\File\read($path)->then(
fn($contents) => Log::debug("Read {$path} in {elapsed}ms", ['elapsed' => $elapsed]),
fn($error) => Log::error("Failed to read {$path}: {$error}")
);
How can I help you explore Laravel packages today?