Undefined variable in PHPStan but it's declared elsewhere
Asked Answered
K

2

7

How do you deal with these scenarios in PHPStan:

  1. Say you're using plain PHP as template engine. E.g.,
// view.php

<b><?=$foo?></b>

  1. Say you have 2 files a.php and b.php
// a.php     
$foo = 'bar';

// b.php     
require 'a.php';     
echo $foo;

PHPStan will both report this as Undefined variable: $foo

How do you deal with this? Can PHPStan be configured to somehow execute your app so it knows that these variables are actually defined during runtime?

Kymry answered 11/12, 2018 at 21:12 Comment(5)
"How do you deal with this?" By not doing that. If you want to use a value in b, don't rely on the assumption that it's been created in a. Instead, explicitly pass it as a parameter to a function/method.Aldus
PHPStan really works best with object oriented code and explicitly defined dependencies.Combative
@AlexHowansky it's actually just a config/bootstrap file divided in to separate files for organization. I guess the only way is to simply just ignore it in phpstan settings.Kymry
"just a config/bootstrap file" Doesn't matter, you've got a monolithic design that depends on global variables. PHPStan is right to alert on that. Put your configuration settings into an object, then pass that object to the things that need it. See dependency injection.Aldus
@AlexHowansky They are actually global constants but some comes from a .env file e.g., $env = loadEnv('../.env'); define('FOO', $env['foo']);Kymry
H
4

You can try to use the phpstan.neon solution provided in phpstan#104 (comment):

You can ignore error for specific variables by using regular expressions, even in specific directories. In your case you can use:

parameters:
    ignoreErrors:
        -
            message: '#Undefined variable: \$foo.*#'
            path: my/directory/*
/** @var string $foo */

echo $foo; // No error

echo $unintededUndeclaredVariable; // Error
Huckster answered 31/3, 2020 at 20:39 Comment(1)
I was able to use this in my project like this: message: '#Variable \$error might not be defined.#'.Meingoldas
D
2

All you need to do is perform a check to ensure the variable is set.

e.g.

if (isset($foo)) {
    echo $foo;
}

or something like the following if you're not wanting to wrap all your code in an if.

if (! isset($foo)) {
    throw new Exception('$foo not set');
}
Deandra answered 6/2, 2019 at 14:41 Comment(2)
Using this, will show "Unreachable statement - code above always terminate". There is an open Issue you all should be subscribed github.com/phpstan/phpstan/issues/104#issuecomment-291877848Huckster
This assumes $foo is always not set, so the check is not useful in static analysis. You should set type as /** @var string|null $foo */Huckster

© 2022 - 2024 — McMap. All rights reserved.