485

Is there a static analysis tool for PHP source files?

The binary itself can check for syntax errors, but I'm looking for something that does more, like:

  • unused variable assignments
  • arrays that are assigned into without being initialized first
  • and possibly code style warnings
  • ...
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
eswald
  • 8,368
  • 4
  • 28
  • 28
  • Related website: [The PHP Quality Assurance Toolchain (phpqatools.org)](http://phpqatools.org/) and another static tool is [PHP_CompatInfo](http://bartlett.laurent-laville.org/). – hakre Dec 25 '13 at 17:12
  • 65
    Righty-o: closed by SO, when clearly this kind of answer is incredibly useful. – Ira Baxter Aug 06 '14 at 10:35
  • 3
    agree. This question is crucial. php lint (php -l file) fails to provide the other half: run the autoload, make sure a function called exists, that variables exists, object properties exist. etc. – Max Nov 07 '14 at 18:03
  • 1
    Phan (for php-7) has [just been released](https://github.com/etsy/phan). – kojiro Dec 08 '15 at 16:09
  • 6
    @IraBaxter useful, but not, strictly speaking, on topic. http://softwarerecs.stackexchange.com/ is probably a more on-topic location. Of course the irony here is that many more developers are familiar with SO than it's sibling... – Wayne Werner Dec 08 '15 at 16:51
  • 7
    The fact that so many people find this type of question useful is probably why softwarerecs now exists. It certainly seemed on topic back when this was the only stack exchange site. Now that there's a clear place for it, does it make sense to migrate? – eswald Dec 08 '15 at 17:12
  • 4
    Closed due to trigger-happy closers. Bah! –  Nov 24 '16 at 18:30
  • 3
    Neither being popular nor being old exempts a question from the rules. Nor are we "trigger happy"; there is no doubt that this question is asking for a library, nor that that kind of question is categorically off-topic. You are simply declaring "this question is *special* and so should be treated differently" without providing any actual reason your question merits such special treatment. – pppery Jun 21 '20 at 00:13

12 Answers12

377

Run php in lint mode from the command line to validate syntax without execution:

php -l FILENAME

Higher-level static analyzers include:

Lower-level analyzers include:

Runtime analyzers, which are more useful for some things due to PHP's dynamic nature, include:

The documentation libraries phpdoc and Doxygen perform a kind of code analysis. Doxygen, for example, can be configured to render nice inheritance graphs with Graphviz.

Another option is xhprof, which is similar to Xdebug, but lighter, making it suitable for production servers. The tool includes a PHP-based interface.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
troelskn
  • 115,121
  • 27
  • 131
  • 155
  • PHP_CodeSniffer is easy to install and easy to use. :) – mcandre Aug 01 '11 at 01:30
  • I know this is an answered question, but still, using `php -l` like this: `find /your/path -name '*.php' | xargs -r php -l` is not working reliably. It often misses files with syntax errors in them. – dimitarvp Aug 24 '11 at 10:38
  • 6
    PHP_CodeSniffer looked very nice to me at the start, but I couldn't for the life of me make it NOT show indentations "errors". It seems it ignores the `--error-severity` option entirely. – dimitarvp Aug 24 '11 at 10:51
  • 24
    +1 for taking 6 hours of my life in trying all these goodies! – Abe Petrillo Feb 13 '12 at 18:48
  • 17
    @dimitko: That's because `php -l` can only read one input file at a time (that is, it won't work if you do `php -l file1.php file2.php`). Instead you need to use the `-n 1` option, which tells `xargs` to only use one input line per command process. That will instead cause it to run `php -l file1.php` followed by `php -l file2.php`, separately. At the same time, you can use `-P ` to run "n" processes at a time, in order to parallelize the execution: `find . -name '*.inc' -o -name '*.php' -print0 | xargs -0 -n1 -P10 php -l` – Joe Apr 05 '12 at 22:07
  • xdebug and xhprof are not static analysis tools. – Ira Baxter May 08 '12 at 23:11
  • 2
    @ira I *did* preface their mention by calling them "runtime analysis options", but perhaps I should have been more explicit? – troelskn May 09 '12 at 08:10
  • 12
    `find /your/path -name '*.php' -exec php -l {} \;` works reliable. – Koen. Aug 08 '12 at 13:11
  • 1
    If you load a lot of extensions in your standard php.ini it can speed things up if you use `php -n -l filename.php` to make it use built-in defaults for ini settings when running checks on a large set of files. – Joeri Sebrechts May 06 '13 at 12:31
  • 13
    **NB**: For the built-in lint function (`php -l`) to work, you must set `display_errors = on` in `php.ini`, otherwise you will only get a generic message about there being syntax errors but no details about what error(s) or what line(s). – Synetech Jul 14 '13 at 04:15
  • 11
    Synetech - Good one. You could override the setting on the command line though, using the `-d` switch. E.g. `php -l -d display_errors=on $FILENAME` – troelskn Jul 14 '13 at 20:10
  • 1
    @dimitko, I concur with your assessment of PHP_CodeSniffer. With one addition. It was very good at finding all my indentation errors (or so it thought, I disagreed in most cases) but it actually failed to spot the actual errors I inserted into my code to test it. – A.Grandt Nov 13 '13 at 06:00
  • I also like [SensioLab's Coding Standards Fixer](http://cs.sensiolabs.org/). This compares against [PSR-1](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md) and [PSR-2](http://www.php-fig.org/psr/psr-2/). What's nice is that it can automatically fix files for you (but if you just want it to list failing files, use its `--dry-run` option). – Sam Oct 08 '14 at 13:50
  • 1
    so, the best way to scan dir with code using 8 processes is something like this - `find . -name "*.php" -print0 | xargs -0 -n1 -P8 php -l` – Oleg Abrazhaev Feb 19 '16 at 07:23
  • SonarQube, and SonarLint plugin makes everything easy peazy – Anfelipe Jun 13 '18 at 14:33
  • Is there a way to make SO reopen this question? The answers are wildly outdated information. – j4k3 Jan 19 '19 at 07:21
  • Sorry for necroposting, but for purpose of checking syntax errors on CI/CD in automation it is essential to have command status code on exit to be non-zero when testing multiple files. For this purpuse I have used the following command: ```(find . -not -path "./vendor/*" -name \*.php -exec echo "php -l -d display_errors=on '{}' &&" \; ; echo "echo Done") | sh - ``` this will produce temp script with combining all lint checks with shell '&&' operator, which will produce non-zero exit code in case of error in any file – Dmitry Valetin Oct 04 '19 at 11:34
  • 1
    My favorite is Psalm (https://psalm.dev/). – Zeal Jan 27 '21 at 05:10
38

Online PHP lint

PHPLint

Unitialized variables check. Link 1 and 2 already seem to do this just fine, though.

I can't say I have used any of these intensively, though :)

Heidelbergensis
  • 475
  • 2
  • 5
  • 18
Martijn Laarman
  • 13,476
  • 44
  • 63
27

For completeness -- also check phpCallGraph.

Till
  • 22,236
  • 4
  • 59
  • 89
26

PHP Mess Detector is awesome and fast.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
aredridel
  • 1,532
  • 14
  • 19
  • 7
    Thank you! I was looking for an awesome. In fact, I refuse to use anything but awesome tools. :) – Prof. Falken Mar 20 '12 at 14:00
  • 2
    It's a start, and it seems to be what Netbeans uses, but I wouldn't trust it completely. Some of its options are just plain odd ("warning" you if you use an else statement??), and there are numerous big bugs in its detections, that haven't even had a response from the developers: https://github.com/phpmd/phpmd/issues – NoBugs Mar 16 '15 at 04:58
  • 1
    else adds cyclomatic complexity and can often be written differently to avoid and else. e.g. if (true) { $x=1; } else { $x =2; } can be re-written: $x=2; if (true) { $x = 1; } – RichardAtHome Nov 22 '17 at 11:34
17

I have tried using php -l and a couple of other tools.

However, the best one in my experience (your mileage may vary, of course) is scheck of pfff toolset. I heard about pfff on Quora (Is there a good PHP lint / static analysis tool?).

You can compile and install it. There are no nice packages (on my Linux Mint Debian system, I had to install the libpcre3-dev, ocaml, libcairo-dev, libgtk-3-dev and libgimp2.0-dev dependencies first) but it should be worth an install.

The results are reported like

$ ~/sw/pfff/scheck ~/code/github/sc/
login-now.php:7:4: CHECK: Unused Local variable $title
go-automatic.php:14:77: CHECK: Use of undeclared variable $goUrl.
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
rjha94
  • 4,292
  • 3
  • 30
  • 37
  • Thank you. It keeps complaining about our dynamic imports, but its other capabilities look good so far. I also needed to install binutils-gold, and scheck needed to be installed in a custom path, but it seems to work now. – eswald Jun 07 '12 at 23:22
  • 1
    @eswald Now a days I am a php mess detector (phpmd) convert. Of all the tools I have tried so far (php code sniffer, scheck, php -l, phpmd), IMHO, phpmd works best for my case. – rjha94 Jun 08 '12 at 03:58
  • Do you know where to find Scheck? – George Katsanos May 23 '13 at 13:52
  • 1
    @GeorgeKatsanos scheck is part of pfff toolset. https://github.com/facebook/pfff – rjha94 May 24 '13 at 09:19
  • 2
    Scheck always give me the error "php checker needs a graph file". The mostly non-existent documentation has no examples. – Robert Bruce Jan 26 '16 at 00:37
  • It is a hell to install all on Mac OS X. – Vladimir Vukanac Mar 17 '19 at 19:58
  • @ Vladimir Vukanac maybe document the steps and publish for everyone? – rjha94 Mar 18 '19 at 17:45
14

See Semantic Designs' CloneDR, a "clone detection" tool that finds copy/paste/edited code.

It will find exact and near miss code fragments, in spite of white space, comments and even variable renamings. A sample detection report for PHP can be found at the website. (I'm the author.)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ira Baxter
  • 93,541
  • 22
  • 172
  • 341
  • 1
    Looking at the site, that seems like an incredible tool. I will be taking a closer look later! Thanks for the link (+1 for "I'm the author" as well) – Eric Cope Oct 29 '11 at 17:53
  • The bane of any conniving undergrad. – wom Mar 15 '12 at 18:55
7

The NetBeans IDE checks for syntax errors, unusued variables and such. It's not automated, but works fine for small or medium projects.

slikts
  • 8,020
  • 1
  • 27
  • 47
6

There a new tool called nWire for PHP. It is a code exploration plugin for Eclipse PDT and Zend Studio 7.x. It enables real-time code analysis for PHP and provides the following tools:

  • Code visualization - interactive graphical representation of components and associations.
  • Code navigation - unique navigation view shows all the associations and works with you while you write or read code.
  • Quick search - search as you type for methods, fields, file, etc.
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
zvikico
  • 9,765
  • 4
  • 38
  • 49
5

PHP PMD (Programming Mistake Detector) and PHP CPD (Copy/Paste Detector) as the former part of PHPUnit.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
erenon
  • 18,838
  • 2
  • 61
  • 93
4

There is RIPS - A static source code analyser for vulnerabilities in PHP scripts. The source code of RIPS is available at SourceForge.

From the RIPS site:

RIPS is a tool written in PHP to find vulnerabilities in PHP applications using static code analysis. By tokenizing and parsing all source code files RIPS is able to transform PHP source code into a program model and to detect sensitive sinks (potentially vulnerable functions) that can be tainted by userinput (influenced by a malicious user) during the program flow. Besides the structured output of found vulnerabilities RIPS also offers an integrated code audit framework for further manual analysis.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
SteAp
  • 11,853
  • 10
  • 53
  • 88
3

There is a tool for static code analysis called PHP Analyzer. PHP Analyzer is now a deprecated project, but you still can access it on the legacy branch.

Among many types of static analysis it also provides basic auto-fixing functionality, see the documentation.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
fatganz
  • 409
  • 1
  • 6
  • 17
2

You may want to try compiling with Facebook's HipHop.

It does a static analysis on the entire project and may be what you're looking for.

GitHub page

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Martin Konecny
  • 57,827
  • 19
  • 139
  • 159