symfony/filesystem
Symfony Filesystem provides practical, cross-platform filesystem utilities for PHP: create/copy/move/remove files and directories, check existence, handle permissions, and more. Part of the Symfony Components with solid documentation and community support.
Installation:
composer require symfony/filesystem
Add to composer.json under require:
"symfony/filesystem": "^8.0"
First Use Case:
Use the Filesystem class for basic file/directory operations:
use Symfony\Component\Filesystem\Filesystem;
$fs = new Filesystem();
// Create a directory
$fs->mkdir('path/to/directory');
// Copy a file
$fs->copy('source.txt', 'destination.txt');
// Remove a file
$fs->remove('file.txt');
Where to Look First:
Symfony\Component\Filesystem\Filesystem class methods (e.g., mkdir, copy, remove, dumpFile, exists).Symfony\Component\Filesystem\Path class for path manipulation (e.g., normalize, getFilename, isAbsolute).dumpFile() to write files atomically, reducing race conditions:
$fs->dumpFile('config.json', json_encode($config));
mirror() to replicate directory structures:
$fs->mirror('source_dir', 'destination_dir');
$normalizedPath = Path::normalize('/path/with/../segments');
$relativePath = Path::makePathRelative('/var/www/html', '/var/www/html/storage');
chmod() for secure file access:
$fs->chmod('file.txt', 0644);
chown() (Linux/macOS only):
$fs->chown('file.txt', 1000);
$tempFile = tempnam(sys_get_temp_dir(), 'prefix');
file_put_contents($tempFile, 'data');
$fs->remove($tempFile); // Cleanup
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->singleton(Filesystem::class, function () {
return new Filesystem();
});
}
use Symfony\Component\Filesystem\Filesystem;
class BackupCommand extends Command
{
protected $fs;
public function __construct(Filesystem $fs)
{
parent::__construct();
$this->fs = $fs;
}
public function handle()
{
$this->fs->mirror(storage_path('app'), backup_path('app'));
}
}
if ($fs->exists('file.txt')) {
$fs->remove('file.txt');
}
try {
$fs->remove('nonexistent_file.txt');
} catch (\RuntimeException $e) {
// Log or handle error
}
Windows vs. UNIX Path Handling:
Path::normalize() to ensure consistency:
$path = Path::normalize('C:\Users\file.txt'); // Converts to forward slashes
Permission Denied Errors:
try-catch blocks and log errors:
try {
$fs->chmod('protected_file.txt', 0777);
} catch (\RuntimeException $e) {
Log::error('Permission denied: ' . $e->getMessage());
}
Temp File Cleanup on Windows:
Filesystem::remove() explicitly:
$fs->remove($tempFile);
Atomic Writes and Race Conditions:
dumpFile() for atomic writes:
$fs->dumpFile('log.txt', $newContent, 0644);
Path Injection Risks:
Path::isAbsolute() and sanitize inputs:
if (!Path::isAbsolute($userInputPath)) {
throw new \InvalidArgumentException('Invalid path');
}
Enable Verbose Output:
Filesystem::getDebug() to log operations:
$fs->getDebug()->setVerbosity(Filesystem::VERBOSITY_DEBUG);
Check Path Normalization:
$normalized = Path::normalize('/path/with/../segments');
dd($normalized);
Handle Windows-Specific Quirks:
str_replace('\\', '/', $path) as a fallback for legacy systems:
$path = str_replace('\\', '/', $path);
$normalized = Path::normalize($path);
Custom Filesystem Adapter:
Filesystem to add custom logic:
class CustomFilesystem extends Filesystem
{
public function customOperation($path)
{
// Custom logic
}
}
Event Listeners for File Operations:
FilesystemEvent (if available) or wrap operations in listeners:
$fs->addListener('preRemove', function ($event) {
// Log or validate before removal
});
Integration with Laravel Events:
event(new FilesystemOperationEvent('copy', ['source.txt', 'destination.txt']));
Disable Symlinks:
$fs = new Filesystem();
$fs->disableSymlinks();
Custom Temp Directory:
putenv('TMPDIR=' . storage_path('framework/tests'));
Case-Insensitive Paths (Windows):
$normalized = Path::normalize(strtolower($path));
Batch Operations:
Filesystem::remove() with an array for multiple files:
$fs->remove(['file1.txt', 'file2.txt']);
Avoid Redundant Checks:
if ($fs->exists($path)) {
// Process file
}
Use mirror() for Large Directories:
$fs->mirror('source_dir', 'destination_dir', null, ['override' => true]);
How can I help you explore Laravel packages today?