6

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?

Community
  • 1
  • 1
IMB
  • 15,163
  • 19
  • 82
  • 140
  • _"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. – Alex Howansky Dec 11 '18 at 21:25
  • PHPStan really works best with object oriented code and explicitly defined dependencies. – Ondřej Mirtes Dec 11 '18 at 23:19
  • @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. – IMB Dec 12 '18 at 05:33
  • 1
    _"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](https://en.wikipedia.org/wiki/Dependency_injection). – Alex Howansky Dec 12 '18 at 14:41
  • @AlexHowansky They are actually global constants but some comes from a .env file e.g., `$env = loadEnv('../.env'); define('FOO', $env['foo']);` – IMB Dec 13 '18 at 05:59

2 Answers2

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
nelson6e65
  • 917
  • 11
  • 14
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');
}
George
  • 2,860
  • 18
  • 31
  • Using this, will show "Unreachable statement - code above always terminate". There is an open Issue you all should be subscribed https://github.com/phpstan/phpstan/issues/104#issuecomment-291877848 – nelson6e65 Mar 31 '20 at 20:06
  • 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 */` – nelson6e65 Oct 24 '21 at 00:53