Feat: PHP 8.4, a test suite and CI - #1
Merged
Conversation
The package now requires PHP 8.4 and declares it: composer.json had no
require section at all. Every parameter, return value and property of src/
carries a type, and the development tooling was brought up to date --
PHPUnit 11.5/12/13, PHP_CodeSniffer 4 (phpcsstandards, not squizlabs),
PHPStan at level 7 without a baseline, and Rector.
The renaming itself was rewritten, because applying the format one pair at a
time over the result of the pair before it is wrong in several ways. Two keys
could not trade names: ['a' => 'b', 'b' => 'a'] renamed a to b and then
renamed that same b back to a, so ['a' => 1, 'b' => 2] came out as ['a' => 2]
and the value of a was simply gone. A chain ['a' => 'b', 'b' => 'c'] carried
the value of a all the way to c for the same reason. Every key is renamed at
once now. Where two keys would end up with the same name the renamed one
wins, and of two renamed ones the one that comes first in the data.
Two more things went wrong inside the splice that moved a key. It was built
with array_merge(), which renumbers integer keys, so renaming one key of
[10 => 'ten', 'ord_id' => 4711, 20 => 'twenty'] renumbered 10 and 20 to 0 and
1. And a renamed key spliced in ahead of an untouched key that already
carried the destination name lost to it, so ['legacy_total' => 12900,
'total' => 0] renamed with ['legacy_total' => 'total'] came out as
['total' => 0].
The shipped global function is gone. src/Functions/array_slice_assoc.php
asked function_exists('array_slice_assoc') before declaring
array_splice_assoc() -- two different names -- so anything else in the
process declaring array_slice_assoc() left the function the package calls
undeclared and every transformation died with a fatal error, while a second
declaration of array_splice_assoc() itself went unnoticed. Nothing needs it
any more.
A format whose from() and to() do not hold the same number of keys throws an
InvalidFormatException instead of the ValueError of array_combine(), and
every exception of the package now extends TransformerException.
Transform::get() spells its argument TransformerInterface|null, which PHP 8.4
no longer deprecates.
A transformer can be told to be recursive, in which case it applies its
format to every array nested in the data, the arrays of a list included. It
is off by default, so a flat transformation is unaffected.
66 tests cover src completely, split into a Unit and a Feature suite; the
feature tests run realistic nested payloads through the package end to end.
Three GitHub Actions workflows run them on PHP 8.4 and 8.5 against both the
lowest and the highest dependencies, next to the coding style check, the
static analysis and the coverage. A Dockerfile and a Makefile run all of it
without PHP on the machine. composer.lock is no longer committed.
This is a breaking major. shetabit/transform-request requires ^2.0 and has to
widen that constraint before it can be used with this release.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of the modernization series across the shetabit packages. This one is framework-agnostic, so there is no Laravel matrix — PHP 8.4/8.5 × lowest/highest dependencies.
The rename logic was rewriting its own output
transform()applied the format one pair at a time, each pass running over the result of the pass before it. So a key that had just been renamed was a candidate for the next rename:['a'=>1,'b'=>2]['a'=>'b','b'=>'a']['a'=>2]— the1is gone['a'=>2,'b'=>1]['a'=>1,'b'=>2,'c'=>3]['a'=>3]— two values gone['a'=>1,'b'=>2]['a'=>'b','b'=>'c']['c'=>2]['b'=>1,'c'=>2]Two columns that were mixed up could not be swapped back, and a chain of renames ran away. All keys are renamed in one pass now.
Alongside that:
['legacy_total'=>12900,'total'=>0]with['legacy_total'=>'total']gave['total'=>0].[10=>'ten','ord_id'=>4711,20=>'twenty']came back with0and1.ValueErrorout ofarray_combine()in the middle of the library. It is anInvalidFormatExceptionnaming both counts now.function_exists()guard named a different function than the one it guarded — it checkedarray_slice_assocbefore declaringarray_splice_assoc, so an application that already had a function of the first name got a fatal error on the second. The whole file is gone (see below).Transform::get()declared an implicitly nullable parameter, which PHP 8.4 deprecates.Also
Transformer::recursive()applies the format to nested arrays, including the arrays inside a list. Off by default, so flat behaviour is unchanged; the package had no nested handling at all before.src. PHPStan level 7, no baseline.Breaking
PHP 8.4 minimum (there was no
requiresection at all). Collision semantics changed as described above.from()/to()declareint|string|arrayand theTransformsetters returnstatic. The globalarray_splice_assoc()and itsautoload.filesentry are removed —shetabit/transform-requestwas checked and does not use it.Transformer::replaceKey()(protected) removed.composer.lockremoved from the repo, as a library should not lock.This lands as the next major.
shetabit/transform-requestpins^2.0.1|^3.0and is ready for it.Verified
composer cigreen on PHP 8.4 and 8.5 × lowest and highest (4 runs), rector clean,composer validate --strictpasses, random test order green.🤖 Generated with Claude Code