You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In PHP <8.0 substr returns false in some cases. In PHP >=8.0 substr returns "" instead in these cases. See https://3v4l.org/6aUKU
When analyzing substr calls with constant arguments, PHPStan uses the substr behavior of the runtime PHP version instead of the PHP version that is being analyzed.
This means that even with a fixed PHP version to analyze (via phpVersion in the config, or composer.json), PHPStan might deduce different types for substr when running on PHP <8.0 vs. running on PHP >=8.0.
Repro
It's hard to show the bug on https://phpstan.org/try, as there is not way to change the runtime PHP version or the analyzed PHP version (at least to my knowledge).
I've almost implemented a fix myself, but couldn't figure out how to test this properly. But I'll share my findings here.
In order to fix this three cases must be considered:
The substr behavior of the runtime PHP version and the analyzed PHP version match: Use the runtime substr.
The runtime PHP version returns false, and the analyzed PHP version returns "": Use the runtime substr and substitute false with "".
The runtime PHP version returns "", and the analyzed PHP version returns false: Find out if this is one of the cases where false should be returned. Otherwise, use the runtime substr.
For the last case the substr implementation of PHP 7.4.33 can be consulted. Concentrating on the cases where false is returned, the logic can be implemented as follows:
Bug report
Description
In PHP <8.0
substr
returnsfalse
in some cases. In PHP >=8.0substr
returns""
instead in these cases. See https://3v4l.org/6aUKUWhen analyzing
substr
calls with constant arguments, PHPStan uses thesubstr
behavior of the runtime PHP version instead of the PHP version that is being analyzed.This means that even with a fixed PHP version to analyze (via
phpVersion
in the config, orcomposer.json
), PHPStan might deduce different types forsubstr
when running on PHP <8.0 vs. running on PHP >=8.0.Repro
It's hard to show the bug on https://phpstan.org/try, as there is not way to change the runtime PHP version or the analyzed PHP version (at least to my knowledge).
This is the best I've come up with to illustrate the expected behavior: https://phpstan.org/r/b7f81641-ee04-44e8-87f2-b02d11e29c06
Hints
I've almost implemented a fix myself, but couldn't figure out how to test this properly. But I'll share my findings here.
In order to fix this three cases must be considered:
substr
behavior of the runtime PHP version and the analyzed PHP version match: Use the runtimesubstr
.false
, and the analyzed PHP version returns""
: Use the runtimesubstr
and substitutefalse
with""
.""
, and the analyzed PHP version returnsfalse
: Find out if this is one of the cases wherefalse
should be returned. Otherwise, use the runtimesubstr
.For the last case the
substr
implementation of PHP 7.4.33 can be consulted. Concentrating on the cases wherefalse
is returned, the logic can be implemented as follows:Code snippet that reproduces the problem
https://phpstan.org/r/b7f81641-ee04-44e8-87f2-b02d11e29c06
Expected output
The result type of
substr
should be determined based on the analyzed PHP version.Did PHPStan help you today? Did it make you happy in any way?
No response
The text was updated successfully, but these errors were encountered: