1. Go to this page and download the library: Download zenstruck/filesystem library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
zenstruck / filesystem example snippets
/** @var \Zenstruck\Filesystem $filesystem */
// read operations
$filesystem->has('some/path'); // bool
$filesystem->node('some/path'); // Zenstruck\Filesystem\Node\File|Zenstruck\Filesystem\Node\Directory or throws NodeNotFound
$filesystem->file('some/path.txt'); // Zenstruck\Filesystem\Node\File or throws NodeNotFound or NodeTypeMismatch (if exists but not a file)
$filesystem->image('some/path.png'); // Zenstruck\Filesystem\Node\File\Image or throws NodeNotFound or NodeTypeMismatch (if exists but not an image)
$filesystem->directory('some/path'); // Zenstruck\Filesystem\Node\Directory or throws NodeNotFound or NodeTypeMismatch (if exists but not a directory)
// write operations (returns Zenstruck\Filesystem\File)
$filesystem->write('some/path.txt', 'string contents'); // write a string
$filesystem->write('some/path.txt', $resource); // write a resource
$filesystem->write('some/path.txt', new \SplFileInfo('path/to/local/file.txt')); // write a local file
$filesystem->write('some/path.txt', $file); // write a Zenstruck\Filesystem\Node\File
$filesystem->copy('from/file.txt', 'dest/file.txt'); // Zenstruck\Filesystem\Node\File (dest/file.txt)
$filesystem->move('from/file.txt', 'dest/file.txt'); // Zenstruck\Filesystem\Node\File (dest/file.txt)
$filesystem->delete('some/file.txt'); // returns self
$filesystem->delete('some/directory'); // returns self
// mkdir operations (returns Zenstruck\Filesystem\Node\Directory)
$filesystem->mkdir('some/directory'); // create an empty directory
$filesystem->mkdir('some/prefix', $directory); // create directory with files from Zenstruck\Filesystem\Node\Directory
$filesystem->mkdir('some/prefix', new \SplFileInfo('path/to/local/directory')); // create directory with files from local directory
$filesystem->chmod('some/file.txt', 'private'); // Zenstruck\Filesystem\Node (some/file.txt)
// utility methods
$filesystem->name(); // string - human-readable name for the filesystem
/** @var \Zenstruck\Filesystem\Node $node */
$node->path(); // Zenstruck\Filesystem\Node\Path
$node->path()->toString(); // string - the full path
(string) $node->path(); // same as above
$node->path()->name(); // string - filename with extension
$node->path()->basename(); // string - filename without extension
$node->path()->extension(); // string|null - file extension
$node->path()->dirname(); // string|null - the parent directory (or null if there is none)
$node->dsn(); // Zenstruck\Filesystem\Node\Dsn
$node->dsn()->toString(); // string - <filesystem-name>://<full-path>
(string) $node->dsn(); // same as above
$node->dsn()->path(); // Zenstruck\Filesystem\Node\Path
$node->dsn()->filesystem(); // string - name of the filesystem this node belongs to
$node->directory(); // Zenstruck\Filesystem\Node\Directory|null - parent directory object (or null if there is none)
$node->visibility(); // string - ie "public" or "private"
$node->lastModified(); // \DateTimeImmutable (in currently configured timezone)
$node->isDirectory(); // bool
$node->isFile(); // bool
$node->isImage(); // bool
$node->exists(); // bool
$node->ensureExists(); // static or throws NodeNotFound
$node->refresh(); // static and clears any cached metadata
$node->ensureDirectory(); // Zenstruck\Filesystem\Node\Directory or throws NodeTypeMismatch (if not a directory)
$node->ensureFile(); // Zenstruck\Filesystem\Node\File or throws NodeTypeMismatch (if not a file)
$node->ensureImage(); // Zenstruck\Filesystem\Node\Image or throws NodeTypeMismatch (if not an image)
/** @var \Zenstruck\Filesystem\Node\File $file */
$file->contents(); // string - the file's contents
$file->stream(); // \Zenstruck\Stream - wrapper for a resource
$file->read(); // "raw" resource
$file->size(); // int
$file->guessExtension(); // string|null - returns extension if available or attempts to guess from mime-type
$file->checksum(); // string - using FilesystemAdapter's default algorithm
$file->checksum('md5'); // string - specify the algorithm
$file->publicUrl(); // string (needs to be configured)
$file->temporaryUrl(new \DateTimeImmutable('+30 minutes')); // string - expiring url (needs to be configured)
$file->temporaryUrl('+30 minutes'); // equivalent to above
$file->tempFile(); // \SplFileInfo - temporary local file that's deleted at the end of the script
use Zenstruck\Filesystem\Node\File\PendingFile;
$file = new PendingFile('/path/to/local/file.txt');
$file->path()->toString(); // "/path/to/local/file.txt"
/** @var \Symfony\Component\HttpFoundation\File\UploadedFile $uploadedFile */
$file = new PendingFile($uploadedFile);
$file->path()->toString(); // $uploadedFile->getClientOriginalName()
/** @var \Zenstruck\Filesystem\Node\File\Image $image */
$image->dimensions(); // Zenstruck\Image\Dimensions
$image->dimensions()->height(); // int
$image->dimensions()->width(); // int
$image->dimensions()->pixels(); // int
$image->dimensions()->aspectRatio(); // float
$image->dimensions()->isSquare(); // bool
$image->dimensions()->isPortrait(); // bool
$image->dimensions()->isLandscape(); // bool
$image->exif(); // array - image exif data if available
$image->iptc(); // array - image iptc data if available
$thumbHash = $image->thumbHash(); // Zenstruck\Image\Hash\ThumbHash (
use Zenstruck\Filesystem\Node\File\Image\PendingImage;
$image = new PendingImage('/path/to/local/file.txt');
$image = new PendingImage($symfonyUploadedFile);
// transform and overwrite
$image->transformInPlace(
function(ManipulationObject $image) {
// make manipulations
return $image;
}
); // self
/** @var Zenstruck\Filesystem\Node\Directory $directory */
// iterate over nodes (non-recursive)
foreach ($directory as $node) {
/** @var Zenstruck\Filesystem\Node $node */
}
// iterate over only files (non-recursive)
foreach ($directory->files() as $file) {
/** @var Zenstruck\Filesystem\Node\File $file */
}
// iterate over only directories (non-recursive)
foreach ($directory->directories() as $dir) {
/** @var Zenstruck\Filesystem\Node\Directory $dir */
}
// recursively iterate
foreach ($directory->recursive() as $node) {
/** @var Zenstruck\Filesystem\Node $node */
}
// advanced filter
$directories = $directory
->recursive()
->files()
->largerThan('10M')
->smallerThan('1G')
->olderThan('30 days ago')
->newerThan('20 days ago')
->matchingFilename('*.twig')
->notMatchingFilename('*.txt.twig')
->matchingPath('/files/')
->notMatchingPath('/exclude/')
->filter(function(File $file) { // custom filter
if ($someCondition) {
return false; // exclude
}
return true; //
use Zenstruck\Filesystem\FlysystemFilesystem;
/** @var \League\Flysystem\FilesystemOperator $operator */
/** @var \League\Flysystem\FilesystemAdapter $adapter */
// create from an already configured Flysystem Filesystem Operator
$filesystem = new FlysystemFilesystem($operator);
// create from an already configured Flysystem Filesystem Adapter
$filesystem = new FlysystemFilesystem($operator);
// create for local directory
$filesystem = new FlysystemFilesystem('/path/to/local/dir');
// create for dsn (see available DSNs below)
$filesystem = new FlysystemFilesystem('flysystem+ftp://user:[email protected]:21/root');
use Zenstruck\Filesystem\ScopedFilesystem;
/** @var \Zenstruck\Filesystem $primaryFilesystem */
$scopedFilesystem = new ScopedFilesystem($primaryFilesystem, 'some/prefix');
// paths are prefixed
$scopedFilesystem
->write('file.txt', 'content')
->path()->toString(); // "some/prefix/file.txt"
;
// prefix is stripped from path
$scopedFilesystem
->write('some/prefix/file.txt', 'content')
->path()->toString(); // "some/prefix/file.txt"
;
use Zenstruck\Filesystem\MultiFilesystem;
/** @var \Zenstruck\Filesystem $filesystem1 */
/** @var \Zenstruck\Filesystem $filesystem2 */
$filesystem = new MultiFilesystem([
'filesystem1' => $filesystem1,
'filesystem2' => $filesystem2,
]);
// prefix paths with a "scheme" as the filesystem's name
$filesystem->file('filesystem1://some/file.txt'); // File from "filesystem1"
$filesystem->file('filesystem2://another/file.txt'); // File from "filesystem2"
// can copy and move across filesystems
$filesystem->copy('filesystem1://file.txt', 'filesystem2://file.txt');
$filesystem->move('filesystem1://file.txt', 'filesystem2://file.txt');
// set a default filesystem for when no scheme is set
$filesystem = new MultiFilesystem(
[
'filesystem1' => $filesystem1,
'filesystem2' => $filesystem2,
],
default: 'filesystem2'
);
$filesystem->file('another/file.txt'); // File from "filesystem2"
use Zenstruck\Filesystem\CacheFilesystem;
use Zenstruck\Filesystem\Node\Mapping;
/** @var \Zenstruck\Filesystem $inner */
/** @var \Psr\Cache\CacheItemPoolInterface $cache */
$filesystem = new CacheFilesystem(
inner: $inner,
cache: $cache,
metadata: [ // array of metadata to cache (see Zenstruck\Filesystem\Node\Mapping)
Mapping::LAST_MODIFIED,
Mapping::SIZE,
],
ttl: 3600, // or null for no TTL
);
$filesystem->write('file.txt', 'content'); // caches metadata
$file = $filesystem->file('file.txt');
$file->lastModified(); // cached value
$file->size(); // cached value
$file->checksum(); // real value (as this wasn't configured to be cached)
$file->contents(); // actually reads the file (contents cannot be cached)
use Zenstruck\Filesystem\LoggableFilesystem;
use Zenstruck\Filesystem\Operation;
use Psr\Log\LogLevel;
/** @var \Zenstruck\Filesystem $inner */
/** @var \Psr\Log\LoggerInterface $logger */
$filesystem = new LoggableFilesystem($inner, $logger);
// operations are logged
$filesystem->write('file.txt', 'content'); // logged as '[info] Writing "string" to "file.txt" on filesystem "<filesystem-name>"'
// customize the log levels for each operation
$filesystem = new LoggableFilesystem($inner, $logger, [
Operation::READ => false, // disable logging read operations
Operation::WRITE => LogLevel::DEBUG,
Operation::MOVE => LogLevel::ALERT,
Operation::COPY => LogLevel::CRITICAL,
Operation::DELETE => LogLevel::EMERGENCY,
Operation::CHMOD => LogLevel::ERROR,
Operation::MKDIR => LogLevel::NOTICE,
]);
use Zenstruck\Filesystem\Event\EventDispatcherFilesystem;
use Zenstruck\Filesystem\Operation;
/** @var \Zenstruck\Filesystem $inner */
/** @var \Psr\EventDispatcher\EventDispatcherInterface $dispatcher */
$filesystem = new EventDispatcherFilesystem($inner, $dispatcher, [
// set these to false or exclude to disable dispatching operation's event
Operation::WRITE => true,
Operation::COPY => true,
Operation::MOVE => true,
Operation::DELETE => true,
Operation::CHMOD => true,
Operation::MKDIR => true,
]);
$filesystem->write('foo', 'bar'); // PreWriteEvent/PostWriteEvent dispatched
$filesystem->mkdir('bar'); // PreMkdirEvent/PostMkdirEvent dispatched
$filesystem->chmod('foo', 'public'); // PreChmodEvent/PostChmodEvent dispatched
$filesystem->copy('foo', 'file.png'); // PreCopyEvent/PostCopyEvent dispatched
$filesystem->delete('foo'); // PreDeleteEvent/PostDeleteEvent dispatched
$filesystem->move('file.png', 'file2.png'); // PreMoveEvent/PostMoveEvent dispatched
;
use Zenstruck\Filesystem\Archive\ZipFile;
$archive = new ZipFile('/local/path/to/archive.zip');
$archive->file('some/file.txt');
$archive->write('another/file.txt', 'content');
(string) $archive; // /local/path/to/archive.zip
use Zenstruck\Filesystem\Archive\ZipFile;
$archive = new ZipFile();
$archive->write('some/file.txt', 'content');
$archive->write('another/file.txt', 'content');
(string) $archive; // /tmp/...
use Zenstruck\Filesystem\Archive\ZipFile;
$archive = new ZipFile();
$archive->beginTransaction(); // start the transaction
$archive->write('some/file.txt', 'content');
$archive->write('another/file.txt', 'content');
$archive->commit(); // actually writes the above files
// optionally pass a progress callback to commit
$archive->commit(function() use ($progress) { // callback is called at most, 100 times
$progress->advance();
});
use Zenstruck\Filesystem\Archive\ZipFile;
// compress a local file
$zipFile = ZipFile::compress(new \SplFileInfo('/some/local/file.txt')); // ZipFile (temp file deleted on script end)
// compress a local directory (all files (recursive) in "some/local/directory" are added to archive)
$zipFile = ZipFile::compress(new \SplFileInfo('some/local/directory'));
/** @var \Zenstruck\Filesystem\Node\File $file */
// compress a filesystem file
$zipFile = ZipFile::compress($file);
/** @var \Zenstruck\Filesystem\Node\Directory $directory */
// compress a filesystem directory
$zipFile = ZipFile::compress($directory);
// compress several local/filesystem files
$zipFile = ZipFile::compress([
new \SplFileInfo('/some/local/file.txt'),
$file,
'customize/path.txt' => $file, // use a string array key to set the path for the file
]);
// customize the output filename (will not be deleted at end of script)
$zipFile = ZipFile::compress(..., filename: 'path/to/archive.zip');
use Zenstruck\Filesystem\Archive\TarFile;
$archive = new TarFile('/local/path/to/archive.tar');
$archive = new TarFile('/local/path/to/archive.tar.gz');
$archive = new TarFile('/local/path/to/archive.tar.bz2');
$archive->file('some/file.txt'); // \Zenstruck\Filesystem\Node\File
use Zenstruck\Filesystem\Test\TestFilesystem;
use Zenstruck\Filesystem\Test\Node\TestDirectory;
use Zenstruck\Filesystem\Test\Node\TestFile
use Zenstruck\Filesystem\Test\Node\TestImage;
/** @var \Zenstruck\Filesystem $filesystem */
$filesystem = new TestFilesystem($filesystem);
$filesystem
->assertExists('foo')
->assertNotExists('invalid')
->assertFileExists('file1.txt')
->assertDirectoryExists('foo')
->assertImageExists('symfony.png')
->assertSame('symfony.png', 'fixture://symfony.png')
->assertNotSame('file1.txt', 'fixture://symfony.png')
->assertDirectoryExists('foo', function(TestDirectory $dir) {
$dir
->assertCount(4)
->files()->assertCount(2)
;
$dir
->recursive()
->assertCount(5)
->files()->assertCount(3)
;
})
->assertFileExists('file1.txt', function(TestFile $file) {
$file
->assertVisibilityIs('public')
->assertChecksum($file->checksum()->toString())
->assertContentIs('contents1')
->assertContentIsNot('foo')
->assertContentContains('1')
->assertContentDoesNotContain('foo')
->assertMimeTypeIs('text/plain')
->assertMimeTypeIsNot('foo')
->assertLastModified('2023-01-01 08:54')
->assertLastModified(function(\DateTimeInterface $actual) {
// ...
})
->assertSize(9)
;
})
->assertImageExists('symfony.png', function(TestImage $image) {
$image
->assertHeight(678)
->assertWidth(563)
;
})
;
$file = $filesystem->realFile('symfony.png'); // \SplFileInfo('/tmp/symfony.png') - deleted at the end of the script
use PHPUnit\Framework\TestCase;
use Zenstruck\Filesystem\Test\InteractsWithFilesystem;
class MyTest extends TestCase
{
use InteractsWithFilesystem;
public function test_1(): void
{
$filesystem = $this->filesystem(); // instance of TestFilesystem wrapping an in-memory filesystem
$filesystem->write('file.txt', 'content');
$filesystem->assertExists('file.txt');
}
}
use PHPUnit\Framework\TestCase;
use Zenstruck\Filesystem;
use Zenstruck\Filesystem\Test\InteractsWithFilesystem;
use Zenstruck\Filesystem\Test\FilesystemProvider;
class MyTest extends TestCase implements FilesystemProvider
{
use InteractsWithFilesystem;
public function test_1(): void
{
$filesystem = $this->filesystem(); // instance of TestFilesystem wrapping the AdapterFilesystem defined below
$filesystem->write('file.txt', 'content');
$filesystem->assertExists('file.txt');
}
public function createFilesystem(): Filesystem|FilesystemAdapter|string
{
return '/some/temp/dir';
}
}
use PHPUnit\Framework\TestCase;
use Zenstruck\Filesystem;
use Zenstruck\Filesystem\Test\InteractsWithFilesystem;
use Zenstruck\Filesystem\Test\FixtureFilesystemProvider;
class MyTest extends TestCase implements FixtureFilesystemProvider
{
use InteractsWithFilesystem;
public function test_1(): void
{
$filesystem = $this->filesystem(); // instance of TestFilesystem wrapping a MultiFilesystem
$filesystem->write('file.txt', 'content'); // accesses your test filesystem
$filesystem->assertExists('file.txt');
$filesystem->copy('fixture://some/file.txt', 'file.txt'); // copy a fixture to your test filesystem
}
public function createFixtureFilesystem(): Filesystem|FilesystemAdapter|string;
{
return __DIR__.'/../fixtures';
}
}
use PHPUnit\Framework\TestCase;
use Zenstruck\Filesystem;
use Zenstruck\Filesystem\Test\ResetFilesystem
use Zenstruck\Filesystem\Test\InteractsWithFilesystem;
use Zenstruck\Filesystem\Test\FilesystemProvider;
class MyTest extends TestCase implements FilesystemProvider
{
use InteractsWithFilesystem, ResetFilesystem;
public function test_1(): void
{
$this->filesystem()->write('file.txt', 'content')
$this->filesystem()->assertExists('file.txt')
}
public function test_2(): void
{
$this->filesystem()->assertNotExists('file.txt'); // file created in test_1 was deleted before this test
}
public function createFilesystem(): Filesystem|FilesystemAdapter|string;
{
return '/some/temp/dir';
}
}
use Zenstruck\Filesystem\Symfony\HttpFoundation\FileResponse;
/** @var \Zenstruck\Filesystem\File $file */
$response = new FileResponse($file); // auto-adds content-type/last-modified headers
// create inline/attachment responses
$response = FileResponse::attachment($file); // auto names by the filename (file.txt)
$response = FileResponse::inline($file); // auto names by the filename (file.txt)
// customize the filename used for the content-disposition header
$response = FileResponse::attachment($file, 'different-name.txt');
$response = FileResponse::inline($file, 'different-name.txt');
use Zenstruck\Filesystem\Symfony\HttpFoundation\ArchiveResponse;
/** @var \SplFileInfo|\Zenstruck\Filesystem\Node\File|\Zenstruck\Filesystem\Node\Directory $what */
$response = ArchiveResponse::zip($what);
$response = ArchiveResponse::zip($what, 'data.zip'); // customize the content-disposition name (defaults to archive.zip)
use Zenstruck\Filesystem\Symfony\Validator\PendingFileConstraint;
use Zenstruck\Filesystem\Symfony\Validator\PendingImageConstraint;
/** @var \Symfony\Component\Validator\Validator\ValidatorInterface $validator */
/** @var \Zenstruck\Filesystem\Node\File $file */
/** @var \Zenstruck\Filesystem\Node\File\Image $image */
$validator->validate($file, new PendingFileConstraint(maxSize: '1M')));
$validator->validate($image, new PendingImageConstraint(maxWidth: 200, maxHeight: 200)));
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.