Skip to content

preg_match param-out is a list, and phpstan kind of agrees, but not enough #12397

Closed
phpstan/phpstan-src
#3899

Description

@rudiedirkx

Bug report

The $match param-out in preg_match($pattern, $string, $match) is always a list (unless named capture groups). Phpstan kind of knows that:

Dumped type: array{0?: string, 1?: non-falsy-string, 2?: numeric-string}

But that's not exactly a list, so it complains when I return that when a list<string> is expected.

I think it's impossible to get a $match where 0 and 2 are set, but 1 is not. And other non-list combinations. PregMatchParameterOutTypeExtension and RegexArrayShapeMatcher should know that.

Code snippet that reproduces the problem

https://phpstan.org/r/5efc781a-6381-4d1b-ac96-cd96f373ece4

Expected output

This exact example is fine, because Phpstan doesn't complain about the return value, but without the if breakout, it does complain, and that's wrong IMO. Even without knowing the preg_match return value, we know that $match is a list.

Unless I am mistaken, and it IS possible to get a non-list array. But I don't think so. See Playground example too. Without the breakout if, Phpstan complains, even though an empty array is a perfectly valid list<string>. And after the if $match is a known list?? something is off here.

Did PHPStan help you today? Did it make you happy in any way?

No response

Activity

  1. ondrejmirtes commented on Jan 8, 2025

    @ondrejmirtes
    Member

    /cc @staabm Is this true? If yes you can set the ConstantArrayType isList constructor argument. Also you can check what list{...} resolves to in TypeNodeResolver. It might be that, or it might be intersection with AccessoryArrayListType.

  2. staabm commented on Jan 8, 2025

    @staabm
    Contributor

    I need to double check. It at least depends on $flags I guess

  3. github-actions commented on Apr 25, 2025

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

  4. locked as resolved and limited conversation to collaborators on Apr 25, 2025
  5. ondrejmirtes commented on Feb 27, 2026

    @ondrejmirtes
    Member

    This wasn't actually fixed, it's exposed after phpstan/phpstan-src#4399 again

  6. added this to the Easy fixes milestone on Feb 27, 2026
  7. unlocked this conversation on Feb 27, 2026
  8. phpstan-bot commented on Feb 27, 2026

    @phpstan-bot
    Contributor

    @rudiedirkx After the latest push in 2.2.x, PHPStan now reports different result with your code snippet:

    @@ @@
    - 8: Dumped type: array{0?: string, 1?: non-falsy-string, 2?: numeric-string}
    -10: Dumped type: array{string, non-falsy-string, numeric-string}
    + 8: Dumped type: list{0?: string, 1?: non-falsy-string, 2?: numeric-string}
    +10: Dumped type: array{non-falsy-string, non-falsy-string, numeric-string}
    Full report
    Line Error
    8 Dumped type: list{0?: string, 1?: non-falsy-string, 2?: numeric-string}
    10 Dumped type: array{non-falsy-string, non-falsy-string, numeric-string}
  9. phpstan-bot commented on Mar 12, 2026

    @phpstan-bot
    Contributor

    Closed via merging phpstan/phpstan-src#5209

  10. github-actions commented on Apr 13, 2026

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

  11. locked as resolved and limited conversation to collaborators on Apr 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions