Continuous integration/Phan

Jump to navigation Jump to search


We perform static analysis of MediaWiki's PHP code base using Phan. MediaWiki core configuration for Phan is in the tests/phan directory. All MediaWiki core patches are analyzed by Phan as part of the CI infrastructure.

Note: If you are looking for the experimental security plugin, see SecurityCheckPlugin

Installing Phan[edit]

Phan requires PHP >= 7.0 to run. This is because Phan analyzes the AST that was added to PHP in version 7. It fully supports analyzing PHP 5 codebases, but the analysis must be run from PHP 7. It also requires the php-ast extension.


For Debian/Ubuntu users, if your system does not come with PHP 7, you can use packages from The repositories have co-installable packages for PHP5 and PHP7, and are what is used in the Wikimedia CI infrastructure.

sudo add-apt-repository ppa:ondrej/php
sudo apt-get update
sudo apt-get install php7.0-cli php7.0-common php7.0-curl php7.0-intl php-memcached php7.0-mysql php-redis php7.0-xmlrpc php7.0-dev php7.0-ldap php7.0-gd php7.0-pgsql php7.0-sqlite3 php7.0-tidy php7.0-phpdbg php7.0-bcmath php7.0-mbstring php7.0-xml php-imagick php-ast php-tideways

Fedora users should update to Fedora 25, which comes with PHP 7. sudo dnf install php-ast composer will install both the ast extension and composer (which is used in the next step).

Getting Phan[edit]


Enter the folder which has your local MediaWiki core git checkout.

For Debian/Ubuntu users, run the following command. Note that after this is done you can only ever run composer with PHP >= 7.0.

php7.0 $(which composer) require etsy/phan:0.8 --dev --prefer-dist

Fedora 25+ users replace php7.0 by php in the command above.


For Debian/Ubuntu users:

$ mkdir ~/git
$ git clone ~/git/phan
$ cd ~/git/phan
$ git checkout tags/0.8.0 -b 0.8.0
$ php7.0 $(which composer) install

Fedora 25 users replace php7.0 by php in the command above.

Running Phan[edit]

Mediawiki core comes with a bash script that will run Phan with a configuration suitable for MediaWiki. This script requires that either your Phan CLI script is included in your PATH environment variable, or that a PHAN environment variable is set pointing to the Phan CLI script in the install you made above.

Running Phan will take a couple minutes (it doesn't output any progress report). After it has run it will emit all the issues it found, along with creating a file tests/phan/issues/issues-<githash> with the same content. <githash> refers to the commit-id of HEAD in the MediaWiki core repository. It also links tests/phan/issues/latest to the specific issue file.


PHAN=/path/to/mediawiki-core/vendor/etsy/phan/phan /path/to/mediawiki-core/tests/phan/bin/phan


PHAN=~/git/phan/phan /path/to/mediawiki-core/tests/phan/bin/phan

Useful CLI flags[edit]

  • -j, --processes <int> : The number of parallel processes to run during the analysis phase. Defaults to 1.
  • -p, --progress-bar : Show progress bar

Upstream Documentation[edit]

Interpreting Results[edit]

Results are in the following structure, one per line. Signatures are in the form used in PHP 7. For our PHP 5 code base the types for arguments and return values are specified in the docblock.

includes/AuthPlugin.php:165 PhanUndeclaredMethod Call to undeclared method \AuthPlugin::allowEmailChange
includes/DerivativeRequest.php:56 PhanParamSignatureMismatch Declaration of function getHeader($name, int $flags = null) should be compatible with function getHeader(string $name, int $flags = null) : array|bool|string defined in includes/WebRequest.php:1028

Suppressing Issues[edit]

Sometimes phan gets it wrong. Or the code is just so hopeless that a large refactor is needed to make the analysis line up. In these cases errors from individual lines can be suppressed with the following format:

/** @suppress PhanUndeclaredMethod some text saying why it was suppressed */

Known Problems[edit]

  • Phan cannot read /** @var Foo $bar */ annotations in the middle of functions. This is a limitation of the PHP AST. The closest workaround currently is to specify @var annotations in the method doc block.