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

Multipart Laravel Package

robtimus/multipart

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require robtimus/multipart
    

    Add to composer.json if using a monorepo or custom package setup.

  2. First Use Case: File Upload Handling Handle a file upload in a Laravel controller:

    use Robtimus\Multipart\MultipartFormData;
    
    public function upload(Request $request)
    {
        $multipart = new MultipartFormData();
        $multipart->addFile(
            'user_file',
            $request->file('file')->getClientOriginalName(),
            fopen($request->file('file')->getPathname(), 'r'),
            $request->file('file')->getMimeType(),
            $request->file('file')->getSize()
        );
        $multipart->addValue('user_id', auth()->id());
    
        // Stream to cURL or buffer for storage
        $buffered = $multipart->buffer();
        // Save $buffered to database or send via API
    }
    
  3. Key Classes to Know:

    • MultipartFormData: For multipart/form-data (e.g., HTML forms, API uploads).
    • MultipartRelated: For embedding resources (e.g., HTML emails with images).
    • MultipartMixed: For email attachments or mixed content.
    • MultipartAlternative: For fallbacks (e.g., HTML/plain-text emails).
  4. Where to Look First:


Implementation Patterns

1. Form Data Uploads (Laravel Integration)

Workflow:

  • Use MultipartFormData to construct payloads for APIs or custom storage.
  • Example: Batch file upload with metadata:
    $multipart = new MultipartFormData();
    foreach ($request->file('files') as $file) {
        $multipart->addFile(
            'files[]', // Note the `[]` for multiple files
            $file->getClientOriginalName(),
            fopen($file->getPathname(), 'r'),
            $file->getMimeType(),
            $file->getSize()
        );
    }
    $multipart->addValue('metadata', json_encode($request->metadata));
    
    // Stream to cURL or buffer
    $buffer = $multipart->buffer();
    $client->post('https://api.example.com/upload', [
        'headers' => ['Content-Type' => $multipart->getContentType()],
        'body' => $buffer,
    ]);
    

Laravel-Specific Tip:

  • Combine with Laravel\Fortify or Laravel\Jetstream for authenticated uploads:
    $multipart->addValue('user_id', auth()->user()->id);
    

2. Email Attachments (Mailable Integration)

Workflow:

  • Use MultipartMixed for emails with attachments or MultipartAlternative for HTML/text fallbacks.
  • Example: Email with embedded image and attachment:
    $mixed = new MultipartMixed();
    $alternative = new MultipartAlternative();
    $alternative->addPart($htmlContent, 'text/html');
    $alternative->addPart($textContent, 'text/plain');
    $mixed->addMultipart($alternative);
    
    // Embedded image (inline)
    $related = new MultipartRelated();
    $related->addPart($htmlContent, 'text/html');
    $related->addInlineFile(
        'logo',
        'logo.png',
        file_get_contents('logo.png'),
        'image/png',
        contentTransferEncoding: 'base64'
    );
    $mixed->addMultipart($related);
    
    // Attachment
    $mixed->addAttachment(
        'report.pdf',
        file_get_contents('report.pdf'),
        'application/pdf'
    );
    
    // Send via Laravel Mail
    Mail::raw((string)$mixed, function ($message) {
        $message->to('user@example.com')
                ->subject('Your Report');
    });
    

Tip:

  • Use (string)$multipart to cast to a string (buffers automatically).
  • For large attachments, stream directly to Swift_Mime or Symfony Mailer.

3. API Integrations (cURL Streaming)

Workflow:

  • Stream multiparts directly to cURL to avoid memory issues with large files.
  • Example: Upload to a third-party API:
    $multipart = new MultipartFormData();
    $multipart->addFile(
        'document',
        'contract.pdf',
        fopen('contract.pdf', 'r'),
        'application/pdf'
    );
    
    $ch = curl_init('https://api.example.com/upload');
    curl_setopt_array($ch, [
        CURLOPT_CUSTOMREQUEST => 'POST',
        CURLOPT_UPLOAD => true,
        CURLOPT_READFUNCTION => [$multipart, 'curlRead'],
        CURLOPT_HTTPHEADER => [
            'Content-Type: ' . $multipart->getContentType(),
            'Authorization: Bearer ' . $token,
        ],
    ]);
    curl_exec($ch);
    curl_close($ch);
    

Pattern:

  • Always call $multipart->finish() before streaming.
  • Use fopen for files and close resources manually (or wrap in a finally block).

4. Validation Middleware

Workflow:

  • Extend Laravel’s FormRequest to validate multipart payloads.
  • Example:
    use Robtimus\Multipart\MultipartFormData;
    
    public function rules()
    {
        return [
            'file' => 'required|file|mimes:pdf,docx|max:10240', // Laravel validation
            'metadata' => 'required|json',
        ];
    }
    
    public function withValidator($validator)
    {
        $validator->after(function ($validator) {
            if ($this->has('file')) {
                $multipart = new MultipartFormData();
                $multipart->addFile(
                    'file',
                    $this->file('file')->getClientOriginalName(),
                    fopen($this->file('file')->getPathname(), 'r'),
                    $this->file('file')->getMimeType()
                );
                $buffer = $multipart->buffer();
                // Custom validation logic (e.g., check file content)
            }
        });
    }
    

5. Progressive Uploads (Laravel + JavaScript)

Workflow:

  • Use MultipartFormData with Laravel’s UploadComponent or custom JavaScript for progress tracking.

  • Example:

    // Frontend (JavaScript)
    const formData = new FormData();
    formData.append('file', fileInput.files[0]);
    formData.append('user_id', userId);
    
    const xhr = new XMLHttpRequest();
    xhr.upload.addEventListener('progress', (e) => {
        console.log(`Uploaded ${e.loaded}/${e.total}`);
    });
    xhr.open('POST', '/upload', true);
    xhr.send(formData);
    
    // Backend (Laravel)
    public function upload(Request $request)
    {
        $multipart = new MultipartFormData();
        $multipart->addFile(
            'file',
            $request->file('file')->getClientOriginalName(),
            fopen($request->file('file')->getPathname(), 'r'),
            $request->file('file')->getMimeType()
        );
        // Process or store $multipart
    }
    

Gotchas and Tips

Pitfalls

  1. Resource Leaks:

    • Issue: Forgetting to close file resources passed to addFile/addPart.
    • Fix: Use finally blocks or wrap in a try-catch:
      $resource = fopen('large_file.bin', 'r');
      try {
          $multipart->addFile('file', $resource, 'application/octet-stream', filesize('large_file.bin'));
          $buffer = $multipart->buffer();
      } finally {
          fclose($resource);
      }
      
  2. Buffering vs. Streaming:

    • Issue: Calling buffer() before finish() may miss parts.
    • Fix: Always call $multipart->finish() before buffering or streaming:
      $multipart->addFile(...);
      $multipart->finish(); // Critical!
      $buffer = $multipart->buffer();
      
  3. Content-Length Mismatches:

    • Issue: cURL fails if Content-Length is missing or incorrect.
    • Fix: Set headers dynamically:
      $headers = ['Content-Type: ' . $multipart->getContentType()];
      if (($length = $multipart->getContentLength()) >= 0) {
          $headers[] = 'Content-Length: ' . $length;
      }
      curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
      
  4. Multiple Files with Same Name:

    • Issue: PHP expects `name[]
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
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