New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot access offset on mixed when using isset()
#8388
Comments
On level 9 you need to check any |
I don't think your additional checks bring any more strictness to the code. The goal is to write better code, not bloated code with useless checks. Is there any case where your checks can detect error that a simple In my exemple, we don't care if the intermediate item are arrays, we just need to access an offset and its value to be a string. I don't know in what case it can trigger an error with the simple check. So if the code is simpler, more readable, more maintenable, more perfomant and as strict, shouldn't it be supported by quality tools? sorry if my formulations seem aggressive or mean, I'm not native English, I try above all to be as clear as possible in my sentences |
The initial problem is $json itself. With mixed it can also be null, or an object, or a resource,.. you get the point. And accessing an offset of e.g. stdClass will fail. And the same then applies to subarrays basically. This is ugly and annoying though, yeah.. See also https://phpstan.org/writing-php-code/narrowing-types and you can do type-narrowing also via assertion (libraries). |
Example of what herndlm is mentioning. mixed is too wide, we need to know that Although, I think maybe we can have some improvements with these issues |
phpstan/phpstan-src#1312 (comment) |
By the way, type of |
@noemi-salaun |
I have an idea to mitigate these issues. Let's create something like Then, relax the condition of this line to $scope->isUndefinedExpressionAllowed($node) && ($isOffsetAccessible->yes() || !isOffsetAccessThrowsFatalError())) We can make |
Oh you are right, I tested Should I close the issue because it's not a false positive? Or I keep it open and rename it for an improvement? |
Unfortunately This was discussed a couple of times before, it's a bit complicated, but most likely the last time we wanted to change this was in my PR where Ondrej explained the situation in phpstan/phpstan-src#1283 (comment) |
Quite related to the question but not that much, I'd wanted to share with you my thoughts and struggles about a problem I was facing, hoping to help others and hoping that others may help me, so we can all write better code! yay
You can also specify/assert them rather than check them. I got quite a few headaches dealing with this problem with I have a @noemi-salaun useless checks are okay in assertions I can see these options for dealing with the code having
Soooo.... IJustStartedUsingAssertions(and PHPDoc comments when necessary) Old code: $language = $Config->getConfig("language", "english"); // returns mixed|null if it can't find the config.
if(is_string($language)) {
$something->foo($language);
} Bad code: $language = $Config->getConfig("language", "english");
/*
* @var string $language Language.
*/
$something->foo($language); New code: $language = $Config->getConfig("language", "english");
assert(is_string($language));
$something->foo($language); @noemi-salaun In your example though, as @herndlm said, I'd rather change the parameter <?php declare(strict_types = 1);
class HelloWorld
{
public function sayHello(mixed $json): string
{
assert(
is_array($json) &&
array_key_exists("Foo", $json) &&
is_array($json["Foo"]) &&
array_key_exists("Bar", $json["Foo"]) &&
is_string($json["Foo"]["Bar"])
);
return $json['Foo']['Bar'];
}
} |
@hydrastro You can also make PHPStan understand that You can use:
All is described in PHPStan documentation on phpstan.org. |
Thanks for the reply @ondrejmirtes In the next few days I'll work on my code and see if I'll find any. |
assertions will protect your logic only at static analysis time. they won't protect your production system (and e.g. therefore don't sanitize your user input) which leads to security problems. assertions are not meant to be enabled in production systems. |
Absolutely! Input sanitization shouldn't absolutely be done with assertions |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Bug report
On PHPStan level 9
When using
isset($data['foo'])
with$data
beingmixed
, PHPStan complains about "Cannot access offset 'foo' on mixed.".Also, when checking for value type, like
is_string($json['Foo']['Bar'])
, the value type is not narrowed.Code snippet that reproduces the problem
https://phpstan.org/r/9b18a65f-f28d-4374-8167-1e94703d9707
Expected output
PHPStan should not report an issue when trying to access offset inside
isset
, and after validating offset withisset
, we should be able to assert the typeDid PHPStan help you today? Did it make you happy in any way?
The text was updated successfully, but these errors were encountered: