vysokeskoly/image-bundle
vysokeskoly/image-bundle is a PHP image bundle for managing, processing, and serving image assets in your application, offering lightweight integration for common upload, transformation, and rendering workflows.
Version 6.0.0 raises the floor to PHP 8.1 and Symfony 6, so the first step is confirming your runtime before touching composer.json.
php -v. Anything below 8.1 means you must stay on the 5.x line.composer require vendor/package:^6.0 --with-all-dependencies
The --with-all-dependencies flag matters here: dropping Symfony 4 and adding Symfony 6 changes transitive constraints, and a plain require will often fail with a conflict against a locked symfony/* version.Where to look first:
php artisan vendor:publish --tag=package-config --force into a scratch directory first), since typed properties in 6.0 often come with tightened config validation.First use case: wire the package into a single, low-risk code path — typically a console command or a queued job — rather than a hot HTTP route. That lets you validate the PHP 8.1 type changes against your own subclassing and serialization before it hits production traffic.
Constructor injection with promoted, typed properties. With 8.1 in play, the idiomatic integration is to let the container resolve the package's services directly:
public function __construct(
private readonly PackageClient $client,
) {}
This is safe as long as you resolve through the container. It breaks if you're instantiating package classes manually with new and the 6.0 constructor now has typed, non-nullable parameters without defaults.
Subclass at your peril — prefer decoration. Because 6.0 adopts PHP 8.1 types, any class you extend from the package inherits typed method signatures. If you have a custom class MyClient extends PackageClient overriding handle(), your override must now declare a compatible return type. The lower-risk pattern is to wrap rather than extend:
final class InstrumentedClient
{
public function __construct(private PackageClient $inner) {}
public function handle(Input $input): Output
{
return tap($this->inner->handle($input), fn () => /* metrics */);
}
}
Bind the decorator in your own service provider and leave the package class untouched.
Enums in config and DTOs. PHP 8.1 features usually means enums have replaced string constants somewhere in the public API. If your config file previously had 'mode' => 'strict', check whether Mode::Strict is now expected. Keeping string values working is often possible via BackedEnum::from(), but don't assume it — read the config stub.
Queue and cache boundaries. Any package object you push onto a queue or into the cache is serialized. Readonly properties and enums serialize differently than plain scalars, and closures inside them won't serialize at all. Keep package DTOs out of job payloads; pass scalars/IDs and rehydrate inside handle().
Test against the real signatures. With typed APIs, Mockery::mock(PackageClient::class) gives you a mock that enforces return types — useful, because it surfaces incompatibilities in your test suite rather than in production. For Laravel-flavoured tests, a fake bound into the container is usually cleaner than mocking the concrete class.
Pin per-branch. If you maintain more than one Laravel version, split your constraints:
"vendor/package": "^5.4" // Laravel 8 branch
"vendor/package": "^6.0" // Laravel 9/10 branch
Symfony 4 support is gone in 6.0, and Symfony 4 era Laravel (6/7/8) can't consume it.
The BC break is invisible in the release notes. "[BC] Use php 8.1 features and types" is the entire warning. In practice this means added return types, readonly properties, possibly never/static return types, and enums replacing constants. Run a static analysis pass (phpstan/psalm at a high level, or rector with a PHP 8.1 set) over any code that touches the package's classes — that's the fastest way to find overrides that no longer match.
Fatal errors, not warnings. A signature mismatch on an overridden method is a compile-time fatal in PHP, so you'll see it immediately in tests — which is good — but it also means a partially-deployed upgrade can white-screen. Deploy behind a maintenance window or a canary.
composer why-not is your debugging tool. If the upgrade refuses to resolve, composer why-not vendor/package 6.0.0 names the exact package holding you back — usually a stale symfony/console or a dev dependency pinned to Symfony 4.
Set config.platform.php in CI. With a hard 8.1 floor, a CI image still on 8.0 will fail at composer install with a confusing platform message. Either bump the image or set:
"config": { "platform": { "php": "8.1.0" } }
Be aware that this only fools Composer — the runtime still needs 8.1, and readonly/enum usage will fatal on 8.0.
Don't trust your local PHP. Developers on 8.2/8.3 are fine (the constraint is a minimum), but a teammate on 8.0 will get resolution failures that look like package bugs. Add "php": "^8.1" to your own require block so Composer reports the problem clearly.
Extension points to review: container bindings (rebind the package's interfaces in your own provider rather than editing published config), macros on any facade the package exposes, and event/listener hooks. All three are the supported way to customise behaviour without inheriting typed signatures.
Rollback plan. Since 5.x supports Symfony 4 and older PHP, keeping a ^5.4 constraint available on your release branch gives you a clean revert path if a typed-signature incompatibility surfaces late. Tag your own release after the upgrade so the constraint change is one composer command away from being undone.
How can I help you explore Laravel packages today?