Storage Adapters#
Pathwise is built on Flysystem 3, so you can use any Flysystem adapter as soon as its package is installed and mounted.
Use Infocyph\Pathwise\Storage\StorageFactory to standardize setup.
What StorageFactory Supports#
StorageFactory::createFilesystem(array $config) accepts:
local driver config:
['driver' => 'local', 'root' => '/srv/storage']prebuilt filesystem:
['filesystem' => $filesystemOperator]adapter instance:
['adapter' => $adapter, 'options' => [...]]custom named drivers registered at runtime.
StorageFactory::mount(string $name, array $config) creates and mounts in one step.
StorageFactory::mountMany(array $mounts) mounts multiple storages at once.
Driver config modes:
direct adapter object:
['driver' => 'aws-s3', 'adapter' => $adapter]constructor arguments for official adapter classes:
['driver' => 'aws-s3', 'constructor' => [$client, $bucket, $prefix]]
StorageFactory also exposes:
StorageFactory::officialDrivers()for official driver metadata.StorageFactory::suggestedPackage($driver)for install guidance.
Official Adapter Coverage#
The following official Flysystem adapters are mapped by driver key:
local->league/flysystem-local->League\Flysystem\Local\LocalFilesystemAdapterftp->league/flysystem-ftp->League\Flysystem\Ftp\FtpAdapterinmemory(alias:in-memory) ->league/flysystem-memory->League\Flysystem\InMemory\InMemoryFilesystemAdapterread-only(alias:readonly) ->league/flysystem-read-only->League\Flysystem\ReadOnly\ReadOnlyFilesystemAdapterpath-prefixing(alias:path-prefix) ->league/flysystem-path-prefixing->League\Flysystem\PathPrefixing\PathPrefixedAdapteraws-s3(aliases:s3,aws) ->league/flysystem-aws-s3-v3->League\Flysystem\AwsS3V3\AwsS3V3Adapterasync-aws-s3->league/flysystem-async-aws-s3->League\Flysystem\AsyncAwsS3\AsyncAwsS3Adapterazure-blob-storage(alias:azure) ->league/flysystem-azure-blob-storage->League\Flysystem\AzureBlobStorage\AzureBlobStorageAdaptergoogle-cloud-storage(alias:gcs) ->league/flysystem-google-cloud-storage->League\Flysystem\GoogleCloudStorage\GoogleCloudStorageAdaptermongodb-gridfs(alias:gridfs) ->league/flysystem-gridfs->League\Flysystem\GridFS\GridFSAdaptersftp-v2(alias:sftp2) ->league/flysystem-sftp-v2->League\Flysystem\PhpseclibV2\SftpAdaptersftp-v3(alias:sftp3) ->league/flysystem-sftp-v3->League\Flysystem\PhpseclibV3\SftpAdapterwebdav->league/flysystem-webdav->League\Flysystem\WebDAV\WebDAVAdapterziparchive(alias:zip) ->league/flysystem-ziparchive->League\Flysystem\ZipArchive\ZipArchiveAdapter
If a package is missing, StorageFactory throws an install hint with the package name.
Basic Local Example#
use Infocyph\Pathwise\Storage\StorageFactory;
use Infocyph\Pathwise\Utils\FlysystemHelper;
StorageFactory::mount('assets', [
'driver' => 'local',
'root' => '/srv/storage/assets',
]);
FlysystemHelper::write('assets://images/logo.txt', 'ok');
Any Adapter Example (S3)#
Install adapter package first (example):
composer require league/flysystem-aws-s3-v3 aws/aws-sdk-php
Then pass the adapter directly:
use Infocyph\Pathwise\Storage\StorageFactory;
use League\Flysystem\AwsS3V3\AwsS3V3Adapter;
use Aws\S3\S3Client;
$client = new S3Client([
'version' => 'latest',
'region' => 'us-east-1',
'credentials' => [
'key' => getenv('AWS_ACCESS_KEY_ID'),
'secret' => getenv('AWS_SECRET_ACCESS_KEY'),
],
]);
$adapter = new AwsS3V3Adapter($client, 'my-bucket', 'app-prefix');
StorageFactory::mount('s3', [
'adapter' => $adapter,
]);
// Works with all Pathwise modules that accept paths:
// s3://uploads/a.pdf
Constructor mode example (official drivers):
StorageFactory::mount('s3', [
'driver' => 's3',
'constructor' => [$client, 'my-bucket', 'app-prefix'],
]);
Read-only/path-prefix wrappers (official adapters):
use League\Flysystem\Local\LocalFilesystemAdapter;
StorageFactory::mount('readonly', [
'driver' => 'read-only',
'constructor' => [new LocalFilesystemAdapter('/srv/storage')],
]);
StorageFactory::mount('prefixed', [
'driver' => 'path-prefixing',
'constructor' => [new LocalFilesystemAdapter('/srv/storage'), 'tenant-a'],
]);
Custom Driver Registration#
If you want environment-driven config, register a custom driver once:
use Infocyph\Pathwise\Storage\StorageFactory;
use League\Flysystem\Filesystem;
use League\Flysystem\Local\LocalFilesystemAdapter;
StorageFactory::registerDriver('tenant-local', function (array $config): Filesystem {
$tenant = (string) ($config['tenant'] ?? 'default');
$root = '/srv/tenants/' . $tenant;
return new Filesystem(new LocalFilesystemAdapter($root));
});
StorageFactory::mount('tenant', [
'driver' => 'tenant-local',
'tenant' => 'acme',
]);
// tenant://docs/report.txt
Helper Functions (autoloaded)#
Global helpers mirror the factory:
createFilesystem(array $config): FilesystemOperatormountStorage(string $name, array $config): FilesystemOperatormountStorages(array $mounts): void
Example:
mountStorage('media', [
'driver' => 'local',
'root' => '/srv/media',
]);
Processor Integration Notes#
UploadProcessor and DownloadProcessor already work with mounted paths.
Examples:
upload destination:
$uploader->setDirectorySettings('s3://uploads')chunk temp dir on mounted storage:
$uploader->setDirectorySettings('s3://uploads', false, 's3://tmp')download root restriction for mounted storage:
$downloads->setAllowedRoots(['s3://uploads'])
Recommended Operational Pattern#
For remote object stores, common production setup is:
receive chunks on fast local temp storage
finalize and write merged object to remote mount
This reduces object churn and upload latency compared with writing every chunk as a separate remote object.