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 Parser Laravel Package

riverline/multipart-parser

Lightweight PHP multipart/form-data parser for handling HTTP uploads and mixed multipart bodies. Extracts fields and files from raw request streams with low memory use, suited for PSR-7 or custom servers needing reliable multipart boundary parsing.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install via Composer:

    composer require riverline/multipart-parser
    
  2. Basic usage – parse a raw request body (e.g., from a PSR-7 Request or raw php://input):

    use Riverline\MultipartParser\Parser;
    
    $body = file_get_contents('php://input'); // or $psr7Request->getBody()->getContents()
    $parser = new Parser($body);
    
    foreach ($parser->getParts() as $part) {
        if ($part->isFile()) {
            echo "File: {$part->getFileName()} ({$part->getMediaType()})\n";
            $content = $part->getContent(); // string contents of the file
        } else {
            echo "Field: {$part->getName()} = {$part->getContent()}\n";
        }
    }
    
  3. First use case: Replace $_FILES/$_POST in API middleware (e.g., for a microframework, Swoole, or custom HTTP server) where superglobals aren’t populated or accessible.


Implementation Patterns

  • Framework Integration (e.g., Slim, Laminas, custom stack)
    Create a middleware that uses Parser to build a PSR-7-compatible body or augment the request with parsed fields/files:

    $parsed = (new Parser($request->getBody()->getContents()))->toArray();
    // $parsed['fields'] and $parsed['files'] are arrays of parsed data
    $request = $request->withParsedBody($parsed['fields']);
    
  • Streaming large uploads
    For memory efficiency, parse from a stream resource instead of loading the entire body:

    $stream = fopen('php://temp', 'r+');
    fwrite($stream, $rawMultipartBody);
    rewind($stream);
    $parser = new Parser($stream);
    
  • Custom file handling
    Stream file contents to disk instead of loading into memory:

    foreach ($parser->getParts() as $part) {
        if ($part->isFile()) {
            $destination = '/uploads/' . basename($part->getFileName());
            file_put_contents($destination, $part->getContent()); // or use stream_copy_to_stream() for large files
        }
    }
    
  • Repeated field names
    Auto-duplicates for repeated field names are grouped in arrays:

    // For multipart with two `tags[]` parts ("php", "laravel")
    $fields = $parser->toArray()['fields'];
    // $fields['tags'] === ['php', 'laravel']
    

Gotchas and Tips

  • Invalid/malformed boundariesParser throws UnexpectedValueException. Always wrap parsing in try/catch.

    try {
        $parser = new Parser($body);
    } catch (UnexpectedValueException $e) {
        // Log error, return 400 Bad Request
    }
    
  • Content-Transfer-Encoding: Only 7bit, 8bit, and binary are supported. quoted-printable or base64 encoding in parts will cause errors unless pre-decoded.

  • Memory management: For large files, avoid $part->getContent() — use getResource() instead and stream to disk or temp:

    $resource = $part->getResource(); // stream resource
    $out = fopen('/tmp/' . $part->getFileName(), 'w');
    stream_copy_to_stream($resource, $out);
    fclose($out);
    
  • No built-in validation: You must manually validate MIME types, extensions, sizes, etc. Check $part->getMediaType() and $part->getHeader('content-length').

  • File names not sanitized: Client-provided filenames may include path traversal (e.g., ../../evil.php). Always sanitize with basename() or pathinfo() before saving.

  • Works with php://input but not $_FILES: This library parses raw payloads — it’s for cases where PHP’s built-in parsing isn’t used (e.g., Content-Type: multipart/form-data sent via curl --data-binary without POST). It does not replace standard $_FILES handling.

  • Debug tip: Log the raw Content-Type header (especially boundary="...") — missing or malformed boundaries are the #1 cause of parsing failures.

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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport
twbs/bootstrap4