Missmatch between PHPDoc and the reality on User::getRoles()
Description
Roles are described as array<string> in symfony/security-core/User/UserInterface.php, whereas they are described as list<string> here src/Security/UserClassBuilder.php.
In itself this is not necessarily problematic, but the function getRoles does not return a list due to array_unique. In fact, array_unique deletes keys on duplicate items, and thus the resulting array is no longer a list which should be an array with sequential keys. (See https://3v4l.org/EMSKK#v8.4.2)
Additional information
There is a mismatch between getRoles() type from symfony/security-core/User/UserInterface.php and the one from src/Security/UserClassBuilder.php. It is thrown by PHPStan.
This error is what made me see the problem.
Method App\Entity\User::getRoles() should return list<string> but returns non-empty-array<string>.
🪪 return.type
💡 non-empty-array<int|string, string> might not be a list.
PHPStan version: 2.1.1 Level max
How to reproduce
- In a symfony project, add a User entity using the maker
php bin/console make:user - Install PHPStan 2
- Set up PHPStan to level max
- Run PHPStan
Solution
See #1646
To fix this, we could change the generated getRoles method as:
// return array_values(array_unique($roles));
$builder->addStmt(
new Node\Stmt\Return_(
new Node\Expr\FuncCall(
new Node\Name('array_values'),
[new Node\Expr\FuncCall(
new Node\Name('array_unique'),
[new Node\Expr\Variable('roles')]
)]
)
)
);
This will reset the keys to be sequential.
Other things that can be done
- We could also update the PHPDoc on UserInterface to match
list<string>
Do not hesitate to give feedback about this, I'm able to update/change if needed :)