Where communities thrive

  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
Repo info
    phan --plugin UnknownElementTypePlugin
    And suppress the issue types you don't plan to use initially
    @TysonAndre Thank you :)
    I have any question with a problem to exclude files from the check via Phan.
    I have a custom config, leave in the project directory ./.phan/config.php. Inside this config file is follow setting.
    'exclude_file_list' => [
    However, after ./vendor/bin/phan --allow-polyfill-parser it checks also this files.
    Thanks a lot for your time and helping.
    The files leave inside the directory ./-/, there is set as include.
    'directory_list' => [
    Tyson Andre
    exclude_file_list are paths relative to the project root. Try -/Medoo.php or ./-/Medoo.php (I forget which). Or use exclude_file_regex, which allows you to pass patterns to match anything, e.g. those basenames
        // A regular expression to match files to be excluded
        // from parsing and analysis and will not be read at all.
        // This is useful for excluding groups of test or example
        // directories/files, unanalyzable files, or files that
        // can't be removed for whatever reason.
        // (e.g. '@Test\.php$@', or '@vendor/.*/(tests|Tests)/@')
        'exclude_file_regex' => '@^vendor/.*/(tests?|Tests?)/@',
    --allow-polyfill-parser may affect whether issues get emitted, but it doesn't affect the list of files to parse/analyze

    Thanks a lot for your fast reply.

    'exclude_file_list' => [

    That works. I tried before the path, like ./-/Medoo.php; but it not worked.

    using phan 2.4.1, i'm getting a PhanSuspiciousWeakTypeComparison with code like
    function foo(array $a = []) { return in_array('something', $a); }
    the message says "... $a of type (no types)" which i assume means it thinks the array is empty, when it reality it only might be empty (and might not, and in some (actual) code paths, IS not).
    ensuring $a has a @param array or whatever[] annotation does not clear the error.
    anyone know if this is intentional, or if there's a workaround (aside from suppressing)?
    Tyson Andre
    I can reproduce it in 2.4.1. It's fixed on dev-master.
    I thought it was introduced in 2.4.2-dev, which is why the fix wasn't released yet
    Lexidor Digital
    Hi, I am so sorry for bothering you all (on new year's day). I've used phan in the past (while version 0.12.13 was still hot of the press). I tried to set up the vscode phan extension, but I must have made a mistake in the process. Running vendor/bin/phan on intentionally broken code reports errors as expected, but there is no red squiggle in the editor. I have the phan extension (1.2.0) enabled globally and I have composer-required phan. My phan.executablePath is set to /usr/bin/php. phan.analyzedProjectDirectory is set to the root of my project. My file association for .php is 'php'. The phan settings in .phan/settings.php check-out (else the stand-alone executable would not work).
    I just realized that I am the only person online. I'll try again tomorrow.
    Lexidor Digital
    Yep, a PEBCAK, as expected.
    Strange that vendor/bin/phan keeps running when it encounters this, but the extension stops running, oh well.
    Tyson Andre

    vendor/bin/phan in phan.analyzedProjectDirectory is newer than the one in /home/lexidor/.vscode/... - The former has the plugin installed, but the latter doesn't. The former would also abort if passed a plugin that didn't exist.

    the phanScriptPath can be used to pass a path to phan or phan.phar

            "phan.phanScriptPath": {
              "type": [
              "default": null,
              "markdownDescription": "Optional (Advanced). If provided, this overrides the Phan script to use, e.g. `/path/to/phan_git_checkout/phan`. (Modifying requires restart)"
    Tyson Andre

    TysonAndre/vscode-php-phan#13 was in the backlog - the largest blocker for that is not having seen any similar language client code to base it or other language client features off of.

    Also, I published vscode-php-phan 1.2.1 just now, which updated the bundled phan from 2.3.1 to 2.4.6 (which has that plugin).

    Lexidor Digital
    Thanks a ton. I did not know that vscode-php-phan bundled a phan version. I thought it grabbed the one in vendor/bin/phan. Thanks a ton for the new version!
    Sarel van der Walt

    I'm being dumb here I think... my composer.json has php version requirement set to >=7.1

        "require": {
            "php": ">=7.1",

    My php version is actually 7.3.14, so that is still in line with the settings.
    When I run php vendor/bin/phan --color I get, among others, this:
    src/AH/AQueueBundle/Manager/QueueManager.php:13 PhanUndeclaredTypeProperty Property \AH\AQueueBundle\Manager\QueueManager->em has undeclared type \Doctrine\ORM\EntityManager

    Here's the thing though, that's only an issue for 7.4 - and only fixable if you use the php 7.4 way of declaring it.

    The code in question is this:

    class QueueManager
        /** @var EntityManager $em */
        protected $em;
        /** @var EntityRepository $repo */
        protected $repo;
    If I change it to protected EntityManager @em then I get (as expected) a PhanSyntaxError because that's a 7.4 thing and I'm on 7.3.
    Tyson Andre
    By default, if Phan emits a PhanSyntaxError, it doesn't analyze the file. So that's why you don't get an issue when you change it to protected EntityManager $em. You can use phan --allow-polyfill-parser and other options to parse and analyze files even if they do have syntax errors.
    You'd need to include the file declaring \Doctrine\ORM\EntityManager in your .phan/config.php's directory_list or file_list, and make sure that it isn't in exclude_file_list or exclude_file_regex. To figure out if it's being parsed, you can use phan --dump-parsed-file-list. Also note that if a file excluded from analysis has a syntax error in the php version used to run Phan, then it's as if the file wasn't parsed as all

    that's only an issue for 7.4 - and only fixable if you use the php 7.4 way of declaring it.

    I'm not 100% certain of what you meant by that.

    Also, Phan currently doesn't use composer.json for anything except phan --init (but there's a ticket in the backlog for using composer.json elsewhere)

    class A {
      public function foo() {
        return static::SOME_CONST;
    class B extends A {
      protected const SOME_CONST = 'hello, world';
    This is causing PhanUnreferencedProtectedClassConstant for B::SOME_CONST. Shouldn't phan be able to see the usage in A? using 2.5.0
    Tyson Andre

    This is deliberate. E.g. if AObject is part of a library, then an application using this library would trigger this bug if they failed to define static::NAME.

    I'd recommend suppressing it if you know all subclasses. Either that or adding a dummy value for SOME_CONST in the base class.

    It analyzes the classes independently of each other. E.g. it doesn't know if something is a framewerk or a library that will have classes it doesn't know about. Also, (new A())->foo() can be called directly.

    See phan/phan#2278 for more details


    i'm not sure this is exactly the same issue. (We did define a dummy const to quiet this, though.)
    I'm not asking about "reference to undeclared constant" in A, but "unreferenced constant" in B.

    I agree that we should not assume SOME_CONST is defined in all subclasses.

    However, there's no assumption involved in the inverse conclusion: we don't need to know anything about other subclasses to know that the parent class (A) does reference static::SOME_CONST. I don't see any possible question about whether B::SOME_CONSTis referenced or not.

    Tyson Andre

    Oh. I was in a hurry and missed the specific issue name - it's should be possible to iterate over all subclasses to check for whether a const of the same name exists, but it's a fairly rare edge case that already has a warning indicating what should be fixed.

    I don't think phan has a method to list all subclasses, and that's been avoided since it's inefficient in the daemon mode/language server (and code that requires listing all subclasses is usually the wrong approach analyzing/parsing only part of a codebase, but should be good enough for dead code detection)

    (And I can't take the normal approach and inherit the reference to the constant in the base class, because there's no constant in the base class)
    I could track references to properties, methods, and class constants that don't exist separately, so they could be inherited

    i was thinking more along the lines of "i'm looking at this specific subclass, so of course i know what the parent class is, so it's obvious that the const is used." I don't think there would be a need to iterate; it could be determined by looking at that one subclass (and its parent(s)). but i don't know if there's something about how phan parses things that would throw a wrench in that.

    thanks for the insights!

    Tyson Andre
    Tracked as phan/phan#3803 - "I could track references to properties, methods, and class constants that don't exist separately, so they could be inherited" (in the base class) was a way that seems viable to do that when just looking at the one subclass
    Hey, has anyone made any effort in adding ide support for phpstorm?
    Tyson Andre

    Phan uses the language server protocol, so it should work with language server clients, although I haven't tested the language client for phpstorm

    https://github.com/phan/phan/wiki/Editor-Support has an example of a command you'd use for "Sublime Text 3", and I'd suggest replacing the psalm command and arguments with the phan command and arguments for the instruction in https://psalm.dev/docs/running_psalm/language_server/#phpstorm

    I haven't tried phpstorm, though

    @TysonAndre Thanks, I gave it a try and got the following exception;
    ERROR: TypeError: Argument 1 passed to phpDocumentor\Reflection\DocBlock\StandardTagFactory::addService() must be an instance of phpDocumentor\Reflection\DocBlock\object, instance of phpDocumentor\Reflection\FqsenResolver given, called in /Users/<user>/Projects/<name>/vendor/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php on line 137 and defined in /Users/<user>/Projects/<name>/vendor/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php:159
    Stack trace:
    #0 /Users/<user>/Projects/<name>/vendor/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php(137): phpDocumentor\Reflection\DocBlock\StandardTagFactory->addService(Object(phpDocumentor\Reflection\FqsenResolver), 'phpDocumentor\\R...')
    #1 /Users/<user>/Projects/<name>/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactory.php(60): phpDocumentor\Reflection\DocBlock\StandardTagFactory->__construct(Object(phpDocumentor\Reflection\FqsenResolver))
    #2 /Users/<user>/Projects/<name>/vendor/felixfbecker/advanced-json-rpc/lib/Dispatcher.php(52): phpDocumentor\Reflection\DocBlockFactory::createInstance()
    #3 /Users/<user>/Projects/<name>/vendor/phan/phan/src/Phan/LanguageServer/LanguageServer.php(176): AdvancedJsonRpc\Dispatcher->__construct(Object(Phan\LanguageServer\LanguageServer), '/')
    #4 /Users/<user>/Projects/<name>/vendor/phan/phan/src/Phan/LanguageServer/LanguageServer.php(288): Phan\LanguageServer\LanguageServer->__construct(Object(Phan\LanguageServer\ProtocolStreamReader), Object(Phan\LanguageServer\ProtocolStreamWriter), Object(Phan\CodeBase), Object(Closure))
    #5 /Users/<user>/Projects/<name>/vendor/phan/phan/src/Phan/LanguageServer/LanguageServer.php(429): Phan\LanguageServer\LanguageServer::Phan\LanguageServer\{closure}(Object(Phan\LanguageServer\ProtocolStreamReader), Object(Phan\LanguageServer\ProtocolStreamWriter))
    #6 /Users/<user>/Projects/<name>/vendor/phan/phan/src/Phan/Phan.php(351): Phan\LanguageServer\LanguageServer::run(Object(Phan\CodeBase), Object(Closure), Array)
    #7 /Users/<user>/Projects/<name>/vendor/phan/phan/src/phan.php(36): Phan\Phan::analyzeFileList(Object(Phan\CodeBase), Object(Closure))
    #8 /Users/<user>/Projects/<name>/vendor/phan/phan/phan(9): require_once('/Users/nicklas....')
    #9 {main}
    (Phan 2.6.1 crashed due to an uncaught Throwable)
    Tyson Andre
    What version of reflection-docblock is this
    What version of php is this, I'd have thought phan required 7.1+ to even run the language server, so I'm not sure how the object exception happened
    oh, you're probably using reflection-docblock 5.0.0 and php 7.1
    Downgrading to phpdocumentor/reflection-docblock=^ should fix that
    I'm guessing composer install|upgrade ran with php 7.2+ and your language server ran with 7.1 locally
    Tyson Andre
    Or install phan in a different directory, or use the phan.phar releases

    Oh, I might have configured something wrong .

    Right, the path to the php binary was wrong and pointed to php 7.1, sorry. So I got the intellij-lsp plugin working with the language server, the errors are displayed but the plugin seems pretty limited. I'll keep using the cli command instead.