Weave 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

Psr7 Pack Laravel Package

symfony/psr7-pack

Symfony PSR-7 pack is a Composer metapackage that installs PSR-7 HTTP message interfaces, a lightweight PSR-7 implementation, and Symfony’s PSR HTTP message bridge for smooth interoperability.

View on GitHub
Deep Wiki
Context7

Getting Started

symfony/psr7-pack is a Composer pack (metapackage), not a library. There is no PHP code, no service provider, no config file — the entire package is a composer.json that pulls in a coherent PSR-7 stack. You interact with it exclusively through Composer.

First steps:

composer require symfony/psr7-pack
composer show symfony/psr7-pack          # what it actually depends on
cat vendor/symfony/psr7-pack/composer.json
composer why nyholm/psr7                 # and php-http/discovery

In a Laravel app you will usually get this package transitively (a PSR-15 middleware, an OAuth2 server, a webhook SDK, a PSR-18 HTTP client) rather than requiring it by hand. First use case: a third-party package type-hints Psr\Http\Message\ServerRequestInterface, ResponseInterface, or Psr\Http\Message\RequestFactoryInterface, and you need working PSR-7 objects plus PSR-17 factories inside a Laravel request lifecycle.

What changed in v1.3.0: the pack swapped nyholm/psr7 for php-http/discovery. php-http/discovery does not ship a PSR-7 implementation — it provides the discovery API (Psr17FactoryDiscovery, Psr18ClientDiscovery, …) and a Composer plugin that auto-adds a concrete implementation when one is missing. That is a behavioural change disguised as a minor release.

Implementation Patterns

Pin the implementation in your root composer.json. Packs are convenience for applications; your app should still be explicit. Keep nyholm/psr7 (or guzzlehttp/psr7) in require so the pack's dependency churn can never silently change your runtime.

Bind discovered factories once, in a service provider. Don't scatter Psr17FactoryDiscovery::find*() calls across controllers — resolve at boot and bind interfaces:

$this->app->singleton(RequestFactoryInterface::class,
    fn () => Psr17FactoryDiscovery::findRequestFactory());
$this->app->singleton(ResponseFactoryInterface::class,
    fn () => Psr17FactoryDiscovery::findResponseFactory());
$this->app->singleton(StreamFactoryInterface::class,
    fn () => Psr17FactoryDiscovery::findStreamFactory());

This gives you one swap point, fails fast at boot rather than mid-request, and makes tests trivial (bind a mock).

Bridging Laravel ⇄ PSR-7. Add symfony/psr-http-message-bridge separately (it is not in this pack) and build a PsrHttpFactory from the three factories above to turn Illuminate\Http\Request into a ServerRequestInterface.

Approve the Composer plugin before CI. Composer 2.2+ blocks plugins by default:

composer config allow-plugins.php-http/discovery true

Treat pack bumps as dependency-graph changes. Pin the pack to 1.2.* if you depend on nyholm/psr7 existing, or upgrade deliberately with composer update symfony/psr7-pack -W and read the composer.lock diff.

Libraries you publish should require psr/http-message, psr/http-factory, or psr/http-client directly — never a pack. Packs are an application/Flex concern.

Stream large files, don't string them. StreamFactoryInterface::createStreamFromFile($upload->getRealPath()) instead of loading getContents() into memory.

Gotchas and Tips

  • v1.3.0 can break composer update silently. Apps on ^1.2 pick it up automatically; if nothing else supplies a PSR-7 implementation and the discovery plugin doesn't run, you get Http\Discovery\Exception\NotFoundException: No PSR-17 factory detected at runtime. Fix: composer require nyholm/psr7 explicitly.
  • Non-interactive installs skip the plugin. composer install -n, --no-plugins, or a locked-down Docker build means discovery never installs an implementation. The failure surfaces only in the container, not locally.
  • Discovery picks by strategy order. With both guzzlehttp/psr7 and nyholm/psr7 present, the chosen implementation can differ between environments — different stream/header/multipart edge-case behaviour. Pin exactly one.
  • Failures are runtime, not install-time. Add a smoke test asserting each find*() returns, or rely on the boot-time bindings above.
  • Avoid discovery in unit tests. Inject factories; discovery resolution adds filesystem/plugin state to otherwise pure tests.
  • PSR-7 is immutable. withHeader() returns a clone — a very common Laravel-side bug when mutating inside a loop.
  • You can't extend a pack. To influence it, use replace/provide in your root composer.json, a Flex recipe, or wrap discovery in your own factory class.
  • Don't composer require it just for curiosity in a lean app — it drags in a PSR stack you may never call. Let consumers pull it transitively, and audit with composer why.
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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums