| Subject | Details |
| :------------- | :---------------------------------------------------------------------------- |
| Plugin | Php Inspections (EA Extended) 4.0.4.1 |
| Language level | PHP 7.1 |
Reproduse code:
/**
* @param string|array<string, string> $mixed
* @param array<string, string> $array
*/
public function __construct($mixed, array $array = [])
{
if (is_array($mixed)) {
$array = $mixed;
}
// do somthing
}
The $array variable can be only a array and a $mixed variable can be a string or array.
If the $mixed variable is array, then i override the $array variable from it.
I explicitly check that the $mixed variable it is a array, but the Php Inspections plugin does not see this.
Changing annotations for parameters does not change anything.
/**
* @param string|array $mixed
* @param array $array
* @phpstan-param string|array<string, string> $mixed
* @phpstan-param array<string, string> $array
*/
public function __construct($mixed, array $array = [])
{
if (is_array($mixed)) {
$array = $mixed;
}
// do somthing
}

No error
PhpStorm 2020.1.2
Build #PS-201.7846.90, built on June 3, 2020
Subscription is active until November 28, 2020
Runtime version: 11.0.7+10-b765.53 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
Windows 10 10.0
GC: ParNew, ConcurrentMarkSweep
Memory: 976M
Cores: 4
Registry: run.processes.with.pty=TRUE
Non-Bundled Plugins: FrameSwitcher, Key Promoter X, com.intellij.ideolog, BashSupport, ru.adelf.idea.dotenv, com.kalessil.phpStorm.phpInspectionsEA, de.espend.idea.php.annotation, fr.adrienbrault.idea.symfony2plugin
@peter-gribanov check https://github.com/php-fig/fig-standards/blob/master/proposed/phpdoc.md
@WinterSilence and what should i see there?
@peter-gribanov type format
@peter-gribanov If i'm not mistaken, this is a limitation of the current implementation of the PhpStorm's type inferer.
Using is_array() on a variable won't restrict it's types to only array (so in your example, string is still a part of the variable possible types)
When PHP EA try to check that $array is assigned only with an array, it fails because the variable contain string
@orklah so, is this a bug in PhpStorm?
More like a limitation than strictly a bug, but yes, the basic issue come from PhpStorm. Not sure if @kalessil can do something about it on his side to limit the issue
@peter-gribanov @orklah
it's happened because
@WinterSilence you are probably not familiar with tools such as PHPStan and Psalm. These tools allow you to use generics. PHPStorm does not support generics and treats them as array. Generics can also be described in separate annotations as in the second example. This does not affect the result.
Using a helper variable solves the problem, but it is not a solution as such. This is a dirty hook.
@peter-gribanov > These tools allow you to use generics.
PHPStorm does not support generics
u post issue to external plugin..
This is a dirty hook.
dirty than if (is_array($mixed)) { $array = $mixed;}? (:
But this plugin relies on PhpStorm's type analysis ;)
As PhpStorm reworked its control flow analysis, it hopefully gets better in the next version.
u post issue to external plugin..
I copied the code from the project only by renaming the variables. I already use generics by default everywhere. As i said, the PHPStorm perceives these annotations as array and your plugin too. That is, there is no difference between array and array<string, string>.
dirty than
I think yes. The ability to use a multiple argument is a feature, and the need to use an helper variable is a bug.
Well, as PHP does not support method overloading, it results in a dirty implementation if try to you "fake" it.
A cleaner variant would be to use "named constructors" (aka. factory methods) for this ;)
/**
* @param string|null $string
* @param array<string, string> $array
*/
private function __construct(?string $string, array $array = [])
{
// do somthing without switching parameters
}
/**
* @param array<string, string> $array
*/
public static function createWithArray(array $array)
{
return new static(null, $array);
}
/**
* @param string $string
* @param array<string, string> $array
*/
public static function createWithStringAndArray(string $string, array $array)
{
return new static($string, $array);
}
@jdreesen ultimately, i came to the same thing, but for a different reason.
As PhpStorm reworked its control flow analysis, it hopefully gets better in the next version.
In last stable release they pushed a big chunk of improvements in their handling of null.
In the next big release (current EAP) they pushed another big chunk with true/false values.
Those two chunks do exactly what is expected in this issue (for example, is_null and is_bool are now used to restrict an union type in their respective release). Let's hope this trend continue, array and string could be next. This is a slow process though, but it will be needed if they ever want to support generics on scalar values
Folks, thank you for support and looking for possible solutions. I'd say that this a 3rd party issue (IDE types resolving). Since PhpStrom pushing types inference forward, I'd wait and see how it goes.
To be clear: I have 0 possibilities to fix the problem.