Skip to content

build: analyse with PHPStan 2 - #10

Draft
galatanovidiu wants to merge 1 commit into
trunkfrom
chore/phpstan-2
Draft

build: analyse with PHPStan 2#10
galatanovidiu wants to merge 1 commit into
trunkfrom
chore/phpstan-2

Conversation

@galatanovidiu

Copy link
Copy Markdown
Contributor

Raises the PHPStan dev dependency to ^2.0. level: max is level 10 there, and src/ analyses clean at it.

How it works

Three adjustments cover the stricter rules.

asStringArray() narrows each element before converting it. Scalars and null convert directly, an object declaring __toString() converts through it, and anything else raises InvalidArgumentException. Nothing reaches a cast from mixed.

Hydration of DTO arrays passes each element through self::asArray(), which asserts array<string, mixed> and so satisfies the fromArray() parameter. The single-DTO hydration paths take the same route.

treatPhpDocTypesAsCertain is off. PHPDoc types on untyped PHP 7.4 properties describe the wire contract, not the runtime value: serialization accepts an already-serialized array where the PHPDoc names a DTO union, so the checks guarding that are reachable.

Compatibility

PHPStan 2 runs on PHP 7.4 and 8.x, so the CI matrix is unchanged.

asStringArray() carries the one behavior change. Every value that converts cleanly keeps its result:

Input Result
['a', 'b'] ['a', 'b']
[1, 2] ['1', '2']
[1.5] ['1.5']
[true, false] ['1', '']
[null] ['']
object declaring __toString() its string value
[[1, 2]], [new stdClass()] InvalidArgumentException

The last row is the change: an array or an object with no __toString() is rejected rather than converted.

Note for reviewers

src/ is generator output. The generator change and the regenerated PHP are committed together so a clean npm run generate reproduces the tree.

This branch and #9 overlap on 10 generated files and on both generator/src/generators/dto.ts and generator/src/writers/index.ts, so the ordering is worth stating. A trial merge of the two runs clean, a fresh npm run generate from the merged generator reproduces the merged tree byte for byte, and composer analyse is clean on the combined result. Either can land first.

`phpstan/phpstan` moves to `^2.0`. `level: max` is level 10 there, and `src/`
analyses clean at it.

`asStringArray()` narrows each element before converting it: scalars and null
convert directly, an object declaring `__toString()` converts through it, and
anything else raises `InvalidArgumentException`. Arrays and objects without
`__toString()` therefore no longer reach a string cast. That is the one
behavior change; every value that already converted cleanly converts to the
same string as before.

Hydration of DTO arrays passes each element through `self::asArray()`, which
asserts `array<string, mixed>` and so satisfies the `fromArray()` parameter.
The single-DTO hydration paths take the same route.

`treatPhpDocTypesAsCertain` is off. PHPDoc types on untyped PHP 7.4 properties
describe the wire contract, not the runtime value: serialization accepts an
already-serialized array where the PHPDoc names a DTO union, so the checks
guarding that are reachable.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant