phar-io/filesystem
phar-io/filesystem is a small PHP utility library from the Phar.io ecosystem that abstracts common filesystem tasks with a clean API. Provides helpers for paths, files, and directories, aiming for safer, testable I/O used by tools like phar-io/phar.
Installation:
composer require phar-io/filesystem
No additional configuration is required—this is a lightweight, dependency-free package.
First Use Case:
Create a filesystem abstraction for a directory (e.g., storage/app):
use PharIo\Filesystem\Filesystem;
$fs = new Filesystem('storage/app');
fileExists($path): Check if a file exists.createFile($path, $content): Write a file.readFile($path): Read a file’s contents.deleteFile($path): Remove a file.listContents($path): List directory contents.Where to Look First:
PharIo\Filesystem\Filesystem (no external docs, so IDE autocompletion is critical).File Operations:
createFile() with a temporary path, then rename (not natively supported; implement manually).
$tempPath = tempnam(sys_get_temp_dir(), 'prefix_');
file_put_contents($tempPath, $content);
$fs->rename($tempPath, $finalPath);
foreach ($fs->listContents('path/to/dir') as $item) {
if ($item->isFile()) {
$fs->deleteFile($item->getPathname());
}
}
Integration with Laravel:
Storage facade to delegate to PharIo\Filesystem for specific paths:
use PharIo\Filesystem\Filesystem;
class PharStorage extends \Illuminate\Filesystem\FilesystemAdapter
{
public function __construct()
{
$this->filesystem = new Filesystem(storage_path('app/phar'));
}
}
Register in config/filesystems.php:
'disks' => [
'phar' => [
'driver' => 'local',
'root' => storage_path('app/phar'),
'adapter' => PharStorage::class,
],
];
PHAR-Specific Use Cases:
PharIo\Filesystem to read/write files inside a PHAR archive:
$pharFs = new Filesystem('phar://myapp.phar');
$pharFs->createFile('config/app.php', file_get_contents('config/app.php'));
Event-Driven Operations:
file.creating) by wrapping methods:
$fs->createFile($path, $content);
event(new FileCreated($path));
No Stream Support:
readFile() load entire files into memory. For large files, use fopen() + fread() directly on the underlying filesystem path.Path Handling:
Filesystem constructor’s root. Use realpath() or dirname(__FILE__) to resolve absolute paths.listContents() fails if $path lacks a trailing slash. Normalize with:
$fs->listContents(rtrim($path, '/') . '/');
Permissions:
chmod() or chown() on the root path if needed:
chmod($fs->getRoot(), 0755);
PHAR-Specific Quirks:
Phar::webPhar() or Phar::running() to enable writes:
$phar = new Phar('myapp.phar', FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::KEY_AS_FILENAME);
$phar->startBuffering();
Verify Root Path:
$fs = new Filesystem('storage/app');
\Log::debug('Filesystem root:', [$fs->getRoot(), realpath($fs->getRoot())]);
Check for Silent Failures:
deleteFile() return bool. Add validation:
if (!$fs->deleteFile($path)) {
throw new \RuntimeException("Failed to delete {$path}");
}
Test with Temporary Directories:
sys_get_temp_dir() for testing to avoid polluting your project:
$tempDir = tempnam(sys_get_temp_dir(), 'test_fs_');
rmdir($tempDir);
$fs = new Filesystem($tempDir);
Custom Filesystem Adapters:
PharIo\Filesystem\FilesystemInterface for S3, FTP, etc.:
class S3Filesystem implements FilesystemInterface
{
public function fileExists($path) {
return $this->s3->objectExists("bucket/{$path}");
}
// ... other methods
}
Event Dispatching:
class LoggingFilesystem implements FilesystemInterface
{
private $fs;
public function __construct(Filesystem $fs) {
$this->fs = $fs;
}
public function createFile($path, $content) {
\Log::info("Creating file: {$path}");
return $this->fs->createFile($path, $content);
}
}
Laravel Service Provider:
$this->app->bind(Filesystem::class, function () {
return new Filesystem(storage_path('app/phar'));
});
How can I help you explore Laravel packages today?