Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Storage Blob Laravel Package

azure-oss/storage-blob

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require azure-oss/storage-blob
    

    Add the package to providers in config/app.php if using Laravel’s service container:

    'providers' => [
        // ...
        AzureOss\Storage\Blob\AzureStorageServiceProvider::class,
    ],
    
  2. Configuration Publish the config file:

    php artisan vendor:publish --provider="AzureOss\Storage\Blob\AzureStorageServiceProvider"
    

    Update .env with your Azure Storage connection string:

    AZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=https;AccountName=...;AccountKey=...;EndpointSuffix=core.windows.net
    
  3. First Use Case Upload a file from Laravel’s public storage to Azure Blob Storage:

    use AzureOss\Storage\Blob\BlobServiceClient;
    use Illuminate\Support\Facades\Storage;
    
    $service = BlobServiceClient::fromConnectionString(config('azure-storage.connection_string'));
    $container = $service->getContainerClient('laravel-uploads');
    $container->createIfNotExists();
    
    $blob = $container->getBlobClient('user-uploads/' . uniqid() . '.jpg');
    $blob->upload(
        Storage::disk('public')->get('path/to/file.jpg'),
        new UploadBlobOptions(contentType: 'image/jpeg')
    );
    

Implementation Patterns

Core Workflows

  1. File Uploads

    • From Local Path:
      $blob->upload(file_get_contents('local/path.jpg'));
      
    • From Stream (Laravel HTTP Request):
      $blob->upload($request->file('image')->get());
      
    • With Metadata/Tags:
      $blob->upload(
          $content,
          new UploadBlobOptions(
              metadata: ['author' => 'John Doe'],
              tags: ['category' => 'profile']
          )
      );
      
  2. File Downloads

    • Streaming to Response (Laravel):
      return response()->stream(
          fn() => $blob->downloadStreaming()->content->detach(),
          200,
          ['Content-Type' => 'application/pdf']
      );
      
    • Save to Local Disk:
      file_put_contents(
          storage_path('app/downloads/' . $blobName),
          $blob->downloadStreaming()->content->getContents()
      );
      
  3. Container Management

    • List Blobs with Pagination:
      $blobs = $container->getBlobs(['maxResults' => 100]);
      foreach ($blobs as $blob) {
          // Process each blob
      }
      
    • Lifecycle Policies (Soft Delete/Archive):
      $container->setBlobServiceProperties([
          'deleteRetentionPolicy' => new DeleteRetentionPolicy(7), // Days
          'containerDeleteRetentionPolicy' => new DeleteRetentionPolicy(30),
      ]);
      
  4. Shared Access Signatures (SAS)

    • Generate SAS Token:
      $sasToken = $blob->generateSasToken(
          new GenerateSasTokenOptions(
              permissions: ['r'], // Read-only
              expiresOn: now()->addHours(1)
          )
      );
      $signedUrl = $blob->getUrl() . '?' . $sasToken;
      
    • Use in Laravel Views:
      <img src="{{ $signedUrl }}" alt="Azure Blob">
      
  5. Integration with Laravel Filesystem

    • Custom Filesystem Driver:
      // config/filesystems.php
      'disks' => [
          'azure' => [
              'driver' => 'azure',
              'connection_string' => env('AZURE_STORAGE_CONNECTION_STRING'),
              'container' => 'laravel-files',
          ],
      ],
      
    • Usage:
      Storage::disk('azure')->put('file.jpg', $content);
      $content = Storage::disk('azure')->get('file.jpg');
      

Gotchas and Tips

Pitfalls

  1. Connection String Security

    • Never commit .env or connection strings to version control.
    • Use Laravel’s env() helper or the config file for sensitive data.
    • Fix: Restrict Azure Storage access keys via IP or service principals.
  2. Large File Uploads

    • Default chunk size for uploads is 4MB. For larger files, use UploadBlobOptions with blockSize:
      $blob->upload(
          $content,
          new UploadBlobOptions(blockSize: 10 * 1024 * 1024) // 10MB blocks
      );
      
    • Tip: Implement resumable uploads for files > 256MB using appendBlock().
  3. CORS Configuration

    • If accessing blobs via browser, ensure CORS rules are set in Azure Portal:
      $container->setCors([
          new CorsRule(
              allowedOrigins: ['https://yourdomain.com'],
              allowedMethods: ['GET', 'HEAD', 'PUT', 'POST', 'DELETE'],
              allowedHeaders: ['*'],
              exposedHeaders: ['Content-Type'],
              maxAgeInSeconds: 86400
          )
      ]);
      
  4. Timeouts and Retries

    • Azure SDK defaults to 3 retries with exponential backoff. Override in config:
      'azure-storage' => [
          'retry' => [
              'max_retries' => 5,
              'delay' => 2, // seconds
          ],
      ],
      
    • Tip: Increase timeout for slow networks:
      $service->setHttpClient(new \GuzzleHttp\Client([
          'timeout' => 60,
      ]));
      
  5. Blob Leasing

    • Always acquire a lease before concurrent operations (e.g., upload + download):
      $lease = $blob->acquireLease(15); // 15-second lease
      try {
          $blob->upload($content);
      } finally {
          $lease->breakLease();
      }
      

Debugging

  1. Enable Logging Add to config/logging.php:

    'channels' => [
        'azure' => [
            'driver' => 'single',
            'path' => storage_path('logs/azure.log'),
            'level' => 'debug',
        ],
    ],
    

    Then enable in AzureStorageServiceProvider:

    $this->app['log']->debug('Azure Blob operation', ['operation' => 'upload']);
    
  2. Common Errors

    • StorageException: Check connection string, container name (must be lowercase), and permissions.
    • 404 Not Found: Verify blob/container exists and SAS tokens (if used) are valid.
    • 403 Forbidden: Ensure the storage account key or SAS token has correct permissions.
  3. Network Issues

    • Use AzureOss\Storage\Blob\Transport\AzureTransport with custom Guzzle middleware for retries:
      $transport = new AzureTransport(
          new \GuzzleHttp\Client([
              'timeout' => 30,
              'middleware' => [
                  new \GuzzleHttp\Middleware\RetryMiddleware([
                      'max_retries' => 3,
                      'retry_delay' => 100,
                  ]),
              ],
          ])
      );
      $service->setTransport($transport);
      

Extension Points

  1. Custom Metadata Handling Extend UploadBlobOptions for project-specific metadata:

    class CustomUploadOptions extends UploadBlobOptions {
        public function __construct(
            public string $userId,
            public string $projectId,
            array $metadata = []
        ) {
            parent::__construct(metadata: array_merge($metadata, [
                'user_id' => $userId,
                'project_id' => $projectId,
            ]));
        }
    }
    
  2. Event Listeners Listen for blob upload/download events (e.g., log or process files):

    $blob->upload($content, new UploadBlobOptions())
         ->then(function () {
             event(new BlobUploaded($blob->getName()));
         });
    
  3. Fluent Interface Chain operations for cleaner code:

    $blob->upload($content)
         ->setMetadata(['custom_key' => 'value'])
         ->generateSasToken(new GenerateSasTokenOptions(permissions: ['r']))
         ->thenReturn($blob->getUrl());
    
  4. Testing Use the AzureOss\Storage\Blob\Mock\MockBlobServiceClient for unit tests:

    $mockService = new MockBlobServiceClient();
    $mockService->setMockResponse('hello.txt', 'Hello World');
    $blob = $mockService->getContainerClient('test')->getBlobClient('hello.txt');
    $this->
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
cadot.eu/make
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky