Setting Up Phan in VSCode

Intro

You can skip straight to “Setting Up Phan VSCode Extension“.

True story – I was in a client’s development environment one day and realised that I was able to login to my account with literally any password I keyed in. I went to the source code (PHP) and found out that somebody added code that looked something like:

if ($password = "very-secret-passphrase") {
    // login without checking password…
}

But that means only if my password is “very-secret-passphrase” will I be able to login right? Wrong. This is because he placed an assignment operator (=) instead of an equality operator (==), so the condition is true always and therefore I can login as any user even if I skipped putting a password.

The fact that code like this is even possible blows my mind 🤯. I decided there has to be some tool out there that can spot this kind of silly mistake to begin with.

Phan: PHP static code analysis

Overlooking that this is bad practice and that there is no proper testing, enter phan – a tool for PHP static code analysis!

I first took note of Phan when Rasmus Lerdorf (the creator of PHP) introduced it in his talk (“25 Years of PHP”). I thought it would be great if it could pick up silly code like checking the condition of an expression that is always true.

And it did (see a live demo running straight from your browser at https://phan.github.io/demo/):

PhanRedundantConditionInGlobalScope Redundant attempt to cast $password of type 'very-secret-passphrase' to truthy in the global scope (likely a false positive)

Out of the box, VSCode doesn’t have this built-in, so I got lazy and see if PHPStorm had it. Turns out they have it in their issue tracker for 6 years now – the Jetbrains folks probably didn’t think it was important.

Setting Up Phan VSCode Extension

The current developer of phan (Tyson Andre) also has created a VSCode extension “PHP Phan (Analyzer)“.

In my setup, I’m using Windows 11, with PHP installed via XAMPP and the PHP bin directory (defaults to C:\xampp\php) placed in my environment PATH.

You can also refer to phan’s wiki for phan setup instructions.

Phan depends on php-ast so I had to install it first. The suggested method of using pecl did not work for me (Fatal error: Array and string offset access syntax with curly braces is no longer supported), so I need to install using the prebuilt windows DLL at https://github.com/nikic/php-ast#installation.

In their file server, I downloaded the latest DLL I can find (php_ast-1.0.16-8.1-ts-vs16-x64.zip) and extracted php_ast.dll to my PHP extension folder at C:\xampp\php\ext\.

I then added to C:\xampp\php\php.ini this line:

extension=php_ast.dll

With php-ast installed, I install phan (as of this writing v5.3.2) globally via composer:

composer global require phan/phan

The executable will then be available phan.

Now cd to your project directory to generate a config file for phan (level 1 is the strictest setting):

phan --init --init-level=1

The file will be at .phan/config.php. You will need to edit the file to set the PHP target version (mine is 7.4) and the directories it reads:

'target_php_version' => '7.4',
'directory_list' => [
    'src',
],

Then the extension needs to be configured. To do this you can edit VSCode’s settings.json (File > Preferences > Settings, enter “@ext:TysonAndre.php-phan” at the search bar):

"phan.analyzedProjectDirectory": "C:/PATH/TO/PROJECT/DIRECTORY/",
"phan.phanScriptPath": "C:/Users/bruce/AppData/Roaming/Composer/vendor/bin/phan"
"phan.allowPolyfillParser": false,
"phan.redundantConditionDetection": true,
"phan.unusedVariableDetection": true,

You can find your phanScriptPath by entering in the command prompt (if you’re in Windows, remember to change the back slashes to forward slashes!):

where phan

I didn’t need to pass in the phanScriptPath since the extension has phan built-in – however, the extension is out of date (current is 5.3.2, the extension is still using 5.1.0), and the warning I want to see is only in the newer version.

Now restart VSCode, and the extension should work:

Phan static code analysis can be viewed from the editor and the problems tab

Note that the extension only analyzes a file when you open it, so the results take a few seconds to show up.

Extension Limitations

My main gripe with this extension is that it is only limited to a single project directory. The author is cognizant of this and writes in the extension settings description: “In the future, this VS Code extension may support analyzing more than one project“.

I had tried substituting C:/PATH/TO/PROJECT/DIRECTORY/ with ${workspaceFolder} (ref: VSCode Variables Reference), but it doesn’t seem to be supported.

Sounds great – but considering this extension hasn’t been updated for almost a year, I wouldn’t place any bets on that.

Even so, you can consider me a big phan – cause phan is phantastic! 😉