phpstan-strict-rules
phpstan-strict-rules copied to clipboard
Warn about implicit cast to int when using bool values as array keys.
Feature request
When using bool values as array keys, then these keys are implicitly casted to integers. This will cause problems when a strict comparison ===
is applied on these keys.
Example Code:
<?php
declare(strict_types=1);
$array = [
true => "true",
false => "false",
];
foreach ($array as $key => $value) {
var_export($key); echo " ";
}
The expected output (if boolean is assumed a valid array key) when running the code is
true
false
but because of int cast, the output is
1
0
Therefore PHPStan should output the following error messages for the given code:
------ -------------------------------------------------------------
Line test.php
------ -------------------------------------------------------------
6 Invalid array key type bool.
7 Invalid array key type bool.
------ -------------------------------------------------------------
While Paslm is giving me the following output:
Psalm output (using commit e93e532):
ERROR: InvalidArrayOffset - 5:10 - Cannot create offset of type bool, expecting array-key
INFO: UnusedVariable - 10:28 - $value is never referenced or the value is not used
Psalm detected 1 fixable issue(s)
Hi, I disagree, PHPStan correctly knows what's going on, it's not a bug to do $array[true] = 'foo';
.
I'm moving this to phpstan-strict-rules where it'd make more sense, but it's not a good fit for the default PHPStan ruleset in the core.
I agree it could be a good rule to add. Float key should be also reported by such rule.
Looking at https://phpstan.org/r/1565b2fd-c3f2-431b-b453-8e28bec67325 the check is already done for things like object.
@ondrejmirtes how do you see such feature ? Should it be a new Rule in the strict-rule repository or can it be an option in the phpstan config, which would be used in the rule https://github.com/phpstan/phpstan-src/blob/86f1690924efe994c4df5fd4dd01d1b0bc713ee3/src/Rules/Arrays/InvalidKeyInArrayItemRule.php#L35 changing the line to
$isSuperType = AllowedArrayKeysTypes::getType($this->strictArrayKey)->isSuperTypeOf($dimensionType);
with
public static function getType(bool $strictArrayKey): Type
{
if ($strictArrayKey) {
return new UnionType([
new IntegerType(),
new StringType(),
]);
}
return new UnionType([
new IntegerType(),
new StringType(),
new FloatType(),
new BooleanType(),
new NullType(),
]);
}