symfony/filesystem
Symfony Filesystem component offers practical utilities for working with files and directories: create, copy, move, remove, mirror, and chmod/chown paths, with robust error handling and portability across platforms. Ideal for safe filesystem operations in PHP apps.
Installation: Add the package via Composer:
composer require symfony/filesystem
For Laravel projects, ensure PHP version compatibility (Symfony Filesystem 7.x for PHP 8.2, 8.x for PHP 8.4+).
First Use Case: Replace a native PHP file operation with Symfony’s utility. Example:
use Symfony\Component\Filesystem\Filesystem;
$fs = new Filesystem();
$fs->dumpFile('/path/to/file.txt', 'Hello, Symfony!');
Or handle directories:
$fs->mirror('/source/dir', '/destination/dir');
Where to Look First:
Filesystem class methods (e.g., copy, remove, exists, mkdir, mirror).Storage::disk('local')->put()) to avoid redundancy.Atomic File Operations:
Use dumpFile() or appendToFile() for safe writes:
$fs->dumpFile($path, $content, 0644); // Atomic write with permissions
Directory Synchronization: Mirror or remove directories recursively:
$fs->mirror($source, $target); // Copy source to target
$fs->remove($directory); // Delete directory and contents
Path Normalization:
Handle cross-platform paths with makePathRelative() or normalizePath():
$relativePath = $fs->makePathRelative($absolutePath, $baseDir);
Permission Management: Set permissions explicitly:
$fs->chmod($path, 0755);
Temporary Files: Create and clean up temp files safely:
$tempFile = tempnam(sys_get_temp_dir(), 'prefix');
$fs->remove($tempFile); // Cleanup
Media Uploads:
Combine with Laravel’s Storage facade for hybrid local/cloud workflows:
$fs->mkdir(storage_path('app/uploads'));
Storage::disk('s3')->put('uploads/file.jpg', file_get_contents($localPath));
Deployment Scripts:
Use mirror() to sync local files to a remote server:
$fs->mirror(__DIR__.'/deploy', '/var/www/html');
Configuration Management: Merge or replace config files atomically:
$fs->dumpFile(config_path('app.php'), $newConfig);
Laravel Service Provider:
Register the Filesystem instance globally:
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->singleton(Filesystem::class, function () {
return new Filesystem();
});
}
Facade (Optional): Create a facade for cleaner syntax:
// app/Facades/FilesystemFacade.php
public static function mirror($source, $target) {
return app(Filesystem::class)->mirror($source, $target);
}
Event Listeners: Trigger filesystem events (e.g., post-upload cleanup):
use Symfony\Component\Filesystem\Filesystem;
event(new FileUploaded($path));
$fs = app(Filesystem::class);
$fs->remove($tempPath); // Cleanup after upload
Testing:
Use Filesystem in tests to mock file operations:
$fs = $this->createMock(Filesystem::class);
$fs->method('exists')->willReturn(true);
PHP Version Mismatch:
Windows-Specific Quirks:
/ vs \) may cause issues. Use normalizePath():
$normalized = $fs->normalizePath($path);
Filesystem::remove() instead of unlink().Permission Errors:
Filesystem methods may throw exceptions on permission failures. Handle with:
try {
$fs->mkdir($dir, 0755);
} catch (\RuntimeException $e) {
Log::error('Failed to create directory: '.$e->getMessage());
}
Race Conditions:
dumpFile()) are safe, but custom logic may introduce races. Prefer built-in methods over manual file_put_contents().Laravel Redundancy:
Storage facade. Use Symfony Filesystem only for local filesystem tasks not covered by Flysystem (e.g., advanced path manipulation).Check Paths:
Use isAbsolutePath() or makePathRelative() to debug path issues:
if (!$fs->isAbsolutePath($path)) {
throw new \InvalidArgumentException('Path must be absolute.');
}
Log Operations: Enable debug logging for filesystem operations:
$fs->dumpFile($path, $content, 0644, true); // Overwrite if exists
Log::debug('Wrote file to '.$path);
Dry Runs:
Test mirror() or remove() in a safe environment first:
$fs->exists($target) // Check before mirroring
|| $fs->mirror($source, $target);
Custom Filesystem Adapter:
Extend Filesystem for domain-specific logic:
class CustomFilesystem extends Filesystem {
public function safeRemove($path) {
if ($this->exists($path)) {
$this->remove($path);
}
}
}
Event Dispatching:
Integrate with Laravel events (e.g., filesystem.created):
$fs->dumpFile($path, $content);
event(new FileCreated($path));
Configuration:
Centralize paths in config/filesystem.php:
'temp_dir' => sys_get_temp_dir(),
'storage_dir' => storage_path('app'),
Testing Utilities:
Create a test helper to mock Filesystem:
// tests/TestCase.php
protected function mockFilesystem(array $responses = []) {
$mock = $this->createMock(Filesystem::class);
foreach ($responses as $method => $response) {
$mock->method($method)->willReturn($response);
}
$this->app->instance(Filesystem::class, $mock);
return $mock;
}
config/filesystem.php).sys_get_temp_dir() if needed:
$fs = new Filesystem();
$fs->mkdir(config('filesystem.temp_dir'));
How can I help you explore Laravel packages today?