v4.0.0
The PHP 8.4 major. It raises the floor to ^8.4 and lands every update that the 8.2 floor was holding back — including the runtime SOAP engine, which is where the consumer impact is.
Upgrading from 3.x
| Change | What it means for you |
|---|---|
php: ^8.2 → ^8.4 |
You cannot install this on PHP 8.2 or 8.3. PHP 8.5 is supported and covered by CI. |
php-soap/ext-soap-engine: ^1.7 → ^1.12 |
A runtime dependency. If you pin it below 1.12 yourself, resolution will conflict. |
VatRate::getDecimalValue() removed |
It was a plain alias of getValue(). Replace it one-for-one. |
VatRate::getValueAsFloat() removed |
Use $rate->getValue()?->toFloat(). Keep the null-safe operator — the removed method had one, and VAT rate values are null for any rate a member state does not levy. |
Both removed methods carried an @deprecated tag since 1.0.0. They were deleted rather than converted to the PHP 8.4 #[\Deprecated] attribute, because a library that raises E_USER_DEPRECATED on a public getter floods consumer logs it does not control.
Why the floor had to move
php-soap/ext-soap-engine is the pivot. 1.8.0 onwards requires PHP 8.3+, and 1.12.0 requires ~8.4.0 || ~8.5.0, so 1.7.0 was the only release installable on the old floor. Its AbusedClient::__doRequest() does not declare the $uriParserClass parameter that php-vcr 1.8.2+ needs — which is what had capped php-vcr at <1.8.2. Neither constraint could move alone.
The same was true of the static-analysis tooling for a different reason: Rector 1.x requires phpstan ^1.x and Rector 2.x requires ^2.x, a mirror-image deadlock in which neither open dependency PR could ever go green by itself. phpstan/phpstan ^2.2.6 and rector/rector ^2.5 therefore land together, which also lets the Rector level set move to UP_TO_PHP_84.
Fixes surfaced by the upgrade
PHPStan 2 found four pieces of dead defensive code in src/. The one worth calling out: SoapVatRetrievalClient::performRequest() guarded its response with instanceof \stdClass, but a /** @var \stdClass */ annotation directly above it asserted the type and made the check unconditionally true. Soap\Engine\Engine::request() declares no return type at all, so the annotation was simply wrong. It is gone and the guard is retained, so it now does what it was written to do.
Relatedly, phpstan.neon lost ten stale ignoreErrors patterns — among them a blanket If condition is always true. that had been masking exactly that finding — and now sets reportUnmatchedIgnoredErrors: true so the list cannot rot silently again.
Also in this release
phpunit/phpunitmoves to^13.0. No test metadata changed: v3.0.0 had already converted everything to attributes. Test doubles that never receive an expectation are nowcreateStub()rather thancreateMock(), which is what PHPUnit 13 asks for.php-vcr/php-vcrmoves to>=1.6.4 <1.12. The lower bound is deliberate and stays.- CI now runs PHP 8.4 and 8.5. Note that development requires 8.4.1 specifically — PHPUnit 13 requires it, and 8.4.1 was the first PHP 8.4 release to ship as GA. The library itself runs on any 8.4.
Full detail, including the reasoning behind each constraint, is in CHANGELOG.md.
Full Changelog: v3.0.0...v4.0.0