league/flysystem-azure-blob-storage
Flysystem Azure Blob Storage adapter sub-split. Provides the Azure Blob Storage filesystem adapter for Flysystem. For issues and pull requests, use the main Flysystem repository: https://github.com/thephpleague/flysystem
composer require league/flysystem-azure-blob-storage — this pulls in Flysystem v3+ and Microsoft’s microsoft/azure-storage-blob SDK (v1.1+).$client = BlobRestProxy::createBlobService(env('AZURE_STORAGE_CONNECTION_STRING'));
$adapter = new AzureBlobStorageAdapter($client, 'my-container');
$filesystem = new Filesystem($adapter);
// Test: Create container first if missing
$client->createContainer('my-container');
$filesystem->write('test.txt', 'Hello Azure');
Storage Blob Data Contributor or equivalent RBAC on the container — connection strings with keys work out-of-the-box, but managed identity/SAS require extra setup (see Gotchas).Storage facade with a custom driver:
// app/Providers/AppServiceProvider.php
public function boot()
{
Storage::extend('azure', function ($app, $config) {
$client = BlobRestProxy::createBlobService($config['connection_string']);
return new Filesystem(new AzureBlobStorageAdapter($client, $config['container']));
});
}
Then use Storage::disk('azure')->put('file.txt', $content) seamlessly..env and reference in config/filesystems.php:
'azure' => [
'driver' => 'azure',
'connection_string' => env('AZURE_STORAGE_CONNECTION_STRING'),
'container' => env('AZURE_CONTAINER', 'default'),
'visibility' => env('AZURE_VISIBILITY', 'private'), // Maps to container ACL
]
$filesystem->getVisibility($path)['visibility'] and migrate using ->setVisibility($path, 'public-read') (maps to Container ACL) or Azure SDK tier operations ($client->setBlobTier(...)).generateBlobSasUri():
$sas = BlobSharedAccessSignatureHelper::generateBlobSasUri(
$client, 'my-container', 'file.jpg',
SharedAccessBlobPolicy::PERMISSION_READ,
now()->addDay()
);
preg_match('/^[a-z0-9][a-z0-9-]*[a-z0-9]$/', $name)).Visibility::PUBLIC requires the container ACL to be Container (not Blob or Private) — configure via $client->setContainerAcl($name, 'container').?, #, % in filenames. Azure URL-encodes paths automatically, but inconsistent encoding can cause 404 Not Found errors — normalize filenames before operations.BlobRestProxy per operation in loops/facades — bind it as a singleton in Laravel’s service container ($this->app->singleton(BlobRestProxy::class, ...)).Flysystem calls in try/catch blocks for ServiceException (e.g., container missing) or OperationTimedOutException — Azure SDKs lack consistent retry logic. Consider adding a retry middleware:
$filesystem = new Filesystem(
new RetryMiddleware($adapter, 3, 200)
);
microsoft/azure-storage-blob (REST-based). The newer azure/azure-storage-blob (guzzle-based) is incompatible — avoid upgrading it unless you patch the adapter manually.How can I help you explore Laravel packages today?