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 Stream Builder Laravel Package

php-http/multipart-stream-builder

Build multipart/form-data PSR-7 streams from fields and files, independent of any specific PSR-7 implementation. Useful for composing HTTP request bodies for uploads and complex forms, with easy integration via Composer in php-http based clients.

View on GitHub
Deep Wiki
Context7

Getting Started

Install via Composer: composer require php-http/multipart-stream-builder. Since this package only builds multipart streams (and doesn’t include a PSR-7/17 implementation), ensure you have a compatible PSR-7/17 library installed (e.g., nyholm/psr7, guzzlehttp/psr7). The package uses php-http/discovery to auto-detect implementations.

First use case: Upload a file to an external service via multipart/form-data.

use Http\Message\MultipartStream\MultipartStreamBuilder;

$builder = new MultipartStreamBuilder();
$builder->addResource('file', fopen('/path/to/report.pdf', 'r'), [
    'filename' => 'report.pdf',
    'headers' => ['Content-Type' => 'application/pdf'],
]);

$stream = $builder->build();
$request = (new GuzzleHttp\Psr7\Request('POST', 'https://api.example.com/upload'))
    ->withHeader('Content-Type', 'multipart/form-data; boundary=' . $stream->getBoundary())
    ->withBody($stream);

Implementation Patterns

  • Bulk or queued uploads: Use reset() to clear internal state between batches (e.g., in Laravel queued jobs processing thousands of documents) — avoids memory leaks and repeated object instantiation.
  • Large file streaming: The builder auto-switches to a temporary file when content exceeds memory limits or streams are non-seekable — ideal for large medical images or video metadata uploads.
  • Custom MIME types: Pass 'mimetype' => 'application/vnd.apple.pkpass' for Apple Wallet passes, or use CustomMimetypeHelper for domain-specific types (e.g., application/x-fhir+json).
  • Duplicate field names: v0.2.0+ allows multiple resources with identical names (e.g., addResource('tags', 'alpha'), addResource('tags', 'beta')) — critical for APIs like Salesforce that expect repeated keys.
  • PSR-18 client integration: Pair with a PSR-18 client (e.g., guzzlehttp/guzzle with php-http/guzzle6-adapter) to build clean, testable API clients.

Gotchas and Tips

  • Missing Content-Length headers: As of v1.4.0, per-part Content-Length headers are not added (RFC 7578 compliant). Most modern servers handle this, but legacy backends expecting explicit lengths may fail — inspect requests with tools like php-http/message-factory or curl -v.
  • Non-readable/non-seekable streams: php://input or WebSocket streams work, but avoid mixing with large unbounded streams (e.g., real-time logs) without manual throttling — temp files may accumulate.
  • basename() isn’t used: Filenames for data:// URIs or streams without names are omitted automatically; don’t rely on finfo_file() or pathinfo() to infer missing filenames.
  • Mimetype gaps: .webp, .heic, and .msg are supported out-of-the-box, but obscure formats (e.g., .spx for SPARC binaries) require manual mimetype overrides.
  • Testing anti-pattern: Avoid building real multipart streams in unit tests. Instead, mock MultipartStreamBuilder to return a pre-generated fixture stream (e.g., store a sample multipart payload as a string and wrap it in a stream).
  • PHP 7.4+ requirement: PHP 8.0–8.5 are fully supported; avoid using with HHVM or legacy environments — no polyfills provided.
  • getBoundary() matters: When sending manually, ensure the Content-Type header includes the exact boundary returned by $stream->getBoundary() — mismatched boundaries cause server-side 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