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

Laminas Httphandlerrunner Laravel Package

laminas/laminas-httphandlerrunner

Laminas HTTP Handler Runner executes PSR-7 request handlers and PSR-15 middleware, emitting generated responses to the client in traditional PHP server environments.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Framing correction (important for stakeholders): this is not a Laravel package. It is a Laminas-maintained, framework-agnostic PSR-7/PSR-15 runtime utility: it marshals a ServerRequestInterface, invokes a RequestHandlerInterface (typically a middleware pipeline), and emits the resulting response through a SAPI emitter. There is no service provider, no facade, no config file, and no Laravel integration surface. Any evaluation must therefore be about narrow, deliberate adoption inside or alongside a Laravel estate, not about plugging it into Laravel's HTTP kernel.

Architecture fit

  • Value proposition is small and precise: RequestHandlerRunner (+ RequestHandlerRunnerInterface), EmitterInterface, SapiEmitter, SapiStreamEmitter, EmitterException. Roughly a bootstrap-and-emit concern, not a framework.
  • Strong fit where we already own PSR-7/PSR-15 code: standalone edge services, internal tools, webhook receivers, or Mezzio/Slim-adjacent services. Weak fit as any part of Laravel's request lifecycle, which is built on Illuminate\Http\Request/Response and its own kernel and middleware contract.
  • The genuinely reusable pieces for a Laravel shop are the emitters — particularly SapiStreamEmitter, which flushes headers/status before streaming the body, useful for large file downloads and progressive responses — and the EmitterException diagnostics (headers_sent filename/line), which materially shorten debugging of "output already started" incidents.

Integration feasibility

  • Technically trivial to install (composer require), BSD-3-Clause (permissive, compatible with proprietary code), typed and Psalm-annotated, PHP 8.x current through 8.4 support.
  • Three feasible integration shapes, in ascending cost:
    1. Emitter-only inside Laravel: take a PSR-7 response from a third-party library (PDF, image, export generators that speak PSR-7) and hand it to SapiEmitter. Low blast radius, immediate value.
    2. Sidecar PSR-15 service: a small standalone PHP service whose public/index.php uses RequestHandlerRunner, sharing the repo/deploy pipeline but not Laravel's process model. Clean separation, no kernel contention.
    3. Pipeline replacement: running PSR-15 middleware as the primary request pipeline. This means abandoning Laravel's kernel, routing, container bindings, and middleware features for that service. Not recommended absent a strategic reason.
  • Bridging PSR-15 into Laravel's kernel (double-passing requests between Illuminate and PSR-7 objects) is possible with third-party shims but adds a conversion layer, duplicate middleware semantics, and a class of subtle request/response fidelity bugs. Treat as a last resort.

Technical risk

  • Code risk: low. Small surface, stable API since 2.0, defensive function_exists-style checks fixed early, exception paths hardened.
  • Ecosystem risk: moderate-to-high for a Laravel context. 73 stars and effectively zero direct dependents means low external validation and a thin talent pool; its real usage is largely indirect via the Laminas/Mezzio ecosystem rather than direct adoption.
  • Maintenance risk: release history is dominated by lockfile/CI/PHP-version maintenance with single-digit contributors per release — signs of a maintained-but-not-invested package. That is acceptable for a 500-line utility, but it means no one is building the Laravel bridge we would want.
  • Forward-compatibility risk: 2.12.0 marks classes @final "in preparation for the next major" — an explicit signal that a v3 with BC breaks is planned. Pin to ^2.x and budget a small upgrade task.
  • Process risk: no formal security policy or SLAs implied by the docs; the project carries a political statement in its README that some stakeholders may flag in procurement/legal review — worth pre-empting rather than discovering late.
  • Data-quality flag: the supplied "last release 2026-09-21" is inconsistent with the changelog evidence (2.12.0 and PHP 8.4 support). Do not quote that date in planning artifacts; verify against Packagist.

Key questions

  • Do we actually have PSR-7 responses in the estate today, or is this speculative? (If speculative, the answer is "no".)
  • Is the target workload long-running (Swoole/RoadRunner/FrankenPHP) or classic PHP-FPM? The SAPI emitters assume php://output and will not behave correctly under worker runtimes without a different EmitterInterface implementation.
  • Who owns the Throwable → 500 path? The runner converts exceptions to responses; if we adopt it, we must wire our own logging/APM middleware or we will lose observability.
  • Is one bounded use case (streamed downloads) worth a new dependency and a second HTTP idiom in the codebase?
  • What is the exit cost if v3 breaks us or the package stalls? (Low — it is replaceable in an afternoon by a ~100-line emitter.)

Integration Approach

Stack fit

  • Laravel application code: adopt only SapiEmitter/SapiStreamEmitter for streaming and file emission where response()->streamDownload() is insufficient. Everything else stays native Laravel.
  • New standalone services: adopt fully, with laminas/laminas-diactoros as the PSR-7/PSR-17 implementation (the package's own test suite favors it) and a PSR-11 container for handler wiring.
  • Do not introduce PSR-15 as a second middleware paradigm inside an existing Laravel service; two competing middleware contracts is a durable maintenance and onboarding tax.

Migration path

  1. Spike (1–2 engineer-days): standalone public/index.php running a three-middleware PSR-15 pipeline behind a feature-flagged route; confirm emitter behavior for normal, streamed, and error responses.
  2. Comparative check against the native equivalent (StreamedResponse, BinaryFileResponse analogues) on memory and time-to-first-byte for a 500 MB download.
  3. If adopted, isolate behind an internal interface (e.g., ResponseEmitter) so the third-party type does not leak into domain code.
  4. Only then consider extending PSR-15 usage to additional sidecar services.

Compatibility

  • Requires psr/http-message ^1.1|^2, psr/http-server-handler, psr/http-server-middleware; 2.6.0+ added PSR-7 v2 support and expanded the message-implementation requirement. Verify no constraint conflict with Laravel's existing PSR-7 dependencies (Nyholm, Guzzle PSR-7) before committing.
  • Pin ^2.12 and record the planned v3 review as a tracked task.

Sequencing

  • Phase 1 (week 1): spike and TTFB/memory benchmark; decision memo.
  • Phase 2: if green, ship emitter-only adoption for one streaming endpoint; instrument error path.
  • Phase 3: evaluate sidecar service only when a service genuinely has no Laravel requirements.
  • Phase 4: quarterly dependency review alongside other Laminas/PSR packages.

Operational Impact

Maintenance

  • Near-zero configuration, no migrations, no runtime services, no scheduled jobs. Operational surface is a Composer constraint plus the emitter's interaction with output buffering and headers_sent.
  • Upgrade cadence: expect minor releases roughly tied to PHP versions and dependency refreshes; budget a half-day per year plus a small v3 migration.

Support

  • Upstream support is community/best-effort via GitHub issues, not a vendor SLA. Internal ownership must be explicit — name a backend owner — because the "who fixes it" answer is otherwise "nobody".
  • Documentation is adequate for the purpose (mkdocs book covering emitters and the runner); no Laravel-specific guidance exists, so internal runbook/ADR is required.

Scaling

  • Stateless and per-request; overhead is PSR-7 object allocation plus the pipeline, negligible against typical Laravel bootstrap.
  • SapiStreamEmitter is the scaling win: constant-memory streaming of large bodies versus buffering whole responses, which reduces per-worker memory and improves TTFB under concurrency.
  • Not suitable for persistent-worker runtimes without a custom emitter; that is a scaling constraint to record, not a defect.

Failure modes

  • EmitterException::forHeadersSent — headers already flushed by stray echo/BOM/whitespace; surfaces filename and line, which is the package's most useful operational feature.
  • Exception inside the handler → the runner emits a 500 through the emitter, bypassing Laravel's exception handler, so error reporting and user-facing error pages diverge unless we add logging middleware.
  • Output buffering interference (nested ob_start, gzip handlers) corrupting or truncating streamed responses.
  • PSR-7 implementation absent or ambiguous → discovery failure at bootstrap; pin the implementation explicitly.
  • Misconfigured Content-Length in streamed responses causing truncated downloads behind proxies.
  • Perceived abandonment: low star count and thin contributor base can trigger dependency-review friction; document the low exit cost to defuse it.

Ramp-up

  • Half a day for a mid-level PHP engineer already comfortable with Laravel middleware; the conceptual shift is PSR-7 immutability and stream handling, which takes ~1–2 days to internalize.
  • No hiring-market leverage: assume zero prior familiarity and rely on internal docs. The 73-star footprint means "find someone who has used this" is not a viable staffing strategy.
  • Overall recommendation: conditional adopt, narrowly scoped — approve for emitter/streaming use and for standalone PSR-15 sidecars, reject as a Laravel request pipeline, and gate on the spike proving a measurable streaming benefit over native StreamedResponse.
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.
unabomber/timezone
delatbabel/contacts
astritzeqiri/g-recaptcha
kevinongko/laravel-genode
developeruz/laravel-analytics
robbiep/afterthedeadline
frankkessler/incontact-laravel-oauth2-rest
jlxh/laravel-userlog
davidmgilo/timetables
qylinfly/role-permission
reflect-digital/conduit
takashato/laravel-vietqr
aitor24/laralang
kraenzle-ritter/entity-relations
dindigital/din-image
pomirleanu/image-colors
sawmainek/laravel-api-generator
delatbabel/jsonresponses
mouhamedfd/permissions-generator
eduplus/qr