PHP S107: constructor function parameters are actually fields, count them differently?

The rule “Functions should not have too many parameters” triggers often when using [PHP 8: Constructor property promotion - stitcher.io](https://constructor promotion in PHP 8) for many properties. Likewise, the rule “Classes should not have too many fields” does trigger less often.
The PHP 8 feature mixes these concepts and so messes with the expected complexity. The problem is that these rules have different defaults, with “fields” being 20 and “parameters” being 7.

Now one could say. If you have so many, put some of them to properties and some of them to parameters. But if you want to use readonly you have to use them in the constructor anyway. And there might be some more edge-cases to think about. IMHO:

  • Any readonly promoted property in the constructor only counts as field, as it can only be set in the constructor.
  • Any non-nullable promoted property in the constructor counts as field AND parameter, as you CAN move it to regular property with a setter and a hasser hasFoo(): bool { return isset($this->foo); }.
  • Any nullable promoted property in the constructor counts as field AND parameter, as you SHOULD move them to a regular property with a setter.
  • Any regular parameter counts as parameter.

Thoughts?

Hello @croensch and welcome to the community!

Thanks for raising awareness on this topic.
The points you are raising are correct, we do not take properly into account promoted properties in our rules.
I have created one ticket to fix this for rule S107 and one for rule S1820.

Thanks.
Best regards,
Rudy

3 Likes