multipart-stream-builder
Build multipart/form-data streams in PHP that work with any PSR-7 implementation.
Repository Health
Technical Analysis
PHP Multipart Stream Builder is a small, focused library from the PHP-HTTP (HTTPlug) project that assembles multipart/form-data request bodies as PSR-7 streams. You add fields, file paths, resources, or existing streams to a builder, and it produces a single combined stream with a generated boundary, correct headers, and inferred content types.
Because it depends only on the PSR-7 stream and factory interfaces (resolving a concrete implementation via php-http/discovery), it stays independent of any specific PSR-7 library, so the same code works whether your project uses Guzzle PSR-7, Nyholm/psr7, or another compliant implementation.
What You Get
- A fluent MultipartStreamBuilder that accepts strings, file paths, resources, and PSR-7 streams as parts
- Automatic boundary generation and the matching Content-Type header for the request
- MIME-type inference through a pluggable mimetype helper, with a custom-mapping option
- PSR-7 implementation independence via php-http/discovery auto-detection
Common Use Cases
- Uploading files to an API that expects multipart/form-data request bodies
- Building mixed form submissions that combine text fields and file attachments
- Writing HTTP client code that must stay portable across different PSR-7 libraries
Under The Hood
Architecture - The public surface is a single MultipartStreamBuilder class (src/MultipartStreamBuilder.php) that accumulates parts in a private $data array, each entry carrying its contents stream and headers; build() walks the parts and concatenates them with a generated boundary into one PSR-7 stream, while getBoundary() and the derived Content-Type header expose what the caller must send. MIME resolution is delegated to a small MimetypeHelper interface with an Apache-derived default (ApacheMimetypeHelper) and a CustomMimetypeHelper for overrides.
Tech Stack - Pure PHP targeting 7.4 and 8.x, depending only on the PSR-7 factory/stream interfaces (psr/http-factory-implementation) and php-http/discovery to locate a concrete stream factory at runtime. PHPUnit (8.5 through 12) drives the test suite; there is no build step beyond Composer autoloading via PSR-4.
Code Quality - The codebase is compact and focused, with docblock-typed properties and a dedicated tests directory (CustomMimetypeHelperTest, FunctionTest, and resource fixtures) plus Scrutinizer coverage reporting. Constructor argument validation throws explicit LogicExceptions, and factory discovery falls back gracefully across PSR-17 and legacy HTTPlug factories.
API Design - Getting started takes only a few lines: instantiate the builder, chain addResource() calls, then build() and read the boundary. Naming is descriptive and the implementation-independence design means consumers never wire up a concrete PSR-7 factory themselves, keeping the boilerplate minimal.