softonic/laravel-psr15-bridge
softonic/laravel-psr15-bridge integrates PSR-15 middleware into Laravel, letting you reuse compatible HTTP middleware within Laravel’s pipeline. It bridges PSR-15 interfaces and Laravel request handling for cleaner interoperability and more portable middleware.
Check your stack before anything else. Version 5.0.0 requires Laravel ^12.0 and PHP ^8.5. There is no compatibility shim — if your app is on Laravel 10/11 or PHP 8.2–8.4, Composer will simply refuse to install it. Verify first:
php -v
composer show laravel/framework | grep versions
Install:
composer require <vendor>/<package>:^5.0
If you are upgrading from 4.x, do this on a dedicated branch with a clean working tree, and treat the install itself as the first test — a failing composer update means you are on the wrong stack, not that something is misconfigured.
Where to look first, in order:
CHANGELOG.md / UPGRADE.md in the package root — 5.0.0 is explicitly non-backward-compatible, so any documented rename, removed config key, or changed default matters more than the new features.config/*.php — publish it (php artisan vendor:publish --provider="Vendor\Package\PackageServiceProvider") and diff it against whatever you had published from 4.x. Stale published config is the single most common upgrade failure.register()/boot() methods — confirms what is bound as singleton vs. scoped, which drives how you inject it.README usage section — read it as if the package were new; do not assume 4.x idioms survived.First use case: wire up one read-only, side-effect-free path (a lookup, a fetch, a formatter) behind a route or artisan command and confirm the container resolves it and config is picked up. Only then move on to anything that writes, dispatches jobs, or hits an external service.
Resolve from the container, don't new it. The package is almost certainly bound in its service provider, and that binding is where config, HTTP client, and cache dependencies get injected. Constructor-inject into controllers, jobs, commands, and listeners:
public function __construct(private PackageClient $client) {}
Facades are fine at the edges (Blade, tinker, quick scripts) but make swapping in fakes and reasoning about scope harder in application code.
Keep configuration in config/ + .env, never inline. Publish the config once, commit it, and drive environment-specific values through env() in the config file only. If you were passing credentials or endpoints as constructor arguments in 4.x, move them to config — arguments that used to work are the first thing a major version drops.
Wrap it behind a thin application-level abstraction. A single App\Services\... class that depends on the package and exposes only the three or four methods your domain needs pays for itself at every major version. On 5.0.0 that means the upgrade touches one file instead of forty, and it gives you a seam for tests.
Queue anything that talks to the network. Wrap package calls in a job with $tries, $backoff, and retryUntil(). Combine with RateLimited middleware if the package hits a third-party API with quotas. This is also how you keep request latency flat when the package's client timeouts change between versions.
Test with fakes at the container boundary. In setUp() or a dedicated trait, bind a fake or Mockery double for the package's contract:
$this->app->instance(PackageClient::class, $fake);
Prefer this over Http::fake() alone — the package may cache, retry, or transform responses, and a container-level fake asserts your integration contract rather than the package's internals.
Upgrade workflow for 4.x → 5.0.0:
^5.0; run composer update <vendor>/<package>.vendor:publish --force into a temp dir, then diff against your committed copy.config:clear, cache:clear, optimize:clear) before running the suite; stale compiled config masks real failures.Multi-app / monorepo: if several apps share a composer.lock or a private metapackage, they must all move to Laravel 12 + PHP 8.5 together — you cannot straddle 4.x and 5.x across apps that share code.
docker-compose.yml, GitHub Actions php-version, Forge/Ploiid/Vapor build config, and any platform block in composer.json.--ignore-platform-reqs to force the install. It will "work" and then fail at runtime with type errors or missing functions. If Composer blocks you, the constraint is telling the truth.config.platform.php is a trap in both directions. If you set it to 8.4 for a shared CI, 5.0.0 will refuse to resolve even though production is on 8.5. Keep it aligned with the lowest runtime you actually deploy.null timeout, disabled verification, changed pagination). Diff explicitly rather than assuming.php artisan config:cache, an env() call outside a config file returns null. Symptom: works locally, breaks in production. Reproduce with config:cache locally before deploying.Class not found, Too few arguments, or Call to undefined method where a deprecation notice would have been in a minor release. Search the package's upgrade guide for each symbol you hit before improvising a fix."^5.0" is right during upgrade; consider "5.0.*" and a tested lockfile for services where a silent minor bump is riskier than missing a patch.boot(): custom resolvers/drivers registered via extend(), publishable migrations, and any Package::macro()-style hooks. Macros and driver registrations are exactly what major versions tend to reshape; confirm they still exist in 5.0.0 before relying on them.composer require <vendor>/<package>:^4.0 plus restoring the previous published config — verify that path works on a branch before you merge, not after.How can I help you explore Laravel packages today?