phpstan-strict-rules icon indicating copy to clipboard operation
phpstan-strict-rules copied to clipboard

Warn about implicit cast to int when using bool values as array keys.

Open markuspoerschke opened this issue 4 years ago • 3 comments

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.
 ------ -------------------------------------------------------------

markuspoerschke avatar Feb 19 '21 17:02 markuspoerschke

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)

markuspoerschke avatar Feb 19 '21 17:02 markuspoerschke

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.

ondrejmirtes avatar Feb 19 '21 17:02 ondrejmirtes

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(),
		]);
	}

VincentLanglet avatar Apr 27 '24 19:04 VincentLanglet