Static analysis is the practice of analyzing code without actually executing it. The analysis can do a wide variety of checks with different tools. I will focus my attention on the most common tools available for PHP code analysis.

For installing some of the tools in this article you will need to have these packages installed on your system:

1
2
3
4
5
sudo apt-get install php-pear
sudo apt-get install php5-xsl
sudo apt-get install php5-dev
sudo apt-get install default-jdk
sudo apt-get install ant

PHP Code Sniffer

PHP Code Sniffer is a tool that helps us make sure our coding style standards are being followed. To install you just need to:

1
sudo pear install PHP_CodeSniffer

In it’s most simple use you can just specify the file or folder you want to sniff:

1
phpcs somefile.php

In real life you will want to specify which coding standard to follow. PHPCS comes with some popular standards build in. You can verify which ones are installed with this command:

1
phpcs -i

And you can specify which standard to use:

1
phpcs --standard=Zend controllers/

Something worth mentioning about PHPCS is that it can also be used to sniff CSS files.

PHP Mess Detector

PHPMD Aims to analyze PHP code and find things like:

  • Possible bugs
  • Suboptimal code
  • Overcomplicated expressions
  • Unused parameters, methods, properties

You can now install PHPMD via pear:

1
2
3
sudo pear channel-discover pear.phpmd.org
sudo pear channel-discover pear.pdepend.org
sudo pear install --alldeps phpmd/PHP_PMD

Now we can run PHPMD against our code. Here is the expected format:

1
phpmd [filename|directory] [report format] [ruleset file]

And here is a real example:

1
2
3
adrian@my-xubuntu:~/Dev/myapp$ phpmd controllers/ text codesize,unusedcode,naming

/home/adrian/Dev/myapp/controllers/IndexController.php:47   Avoid variables with short names like $db. Configured minimum length is

PHPUnit

PHPUnit is the most widely used tool for unit testing PHP code. You can install it via pear:

1
2
3
sudo pear channel-discover pear.phpunit.de
sudo pear channel-discover pear.symfony.com
sudo pear install --alldeps phpunit/PHPUnit

For running unit tests you need to create a test suite. I talk a little about the subject in Test driven development with Zend Framework.

To run the test suite you just need to do:

1
phpunit TestSuite.php

PHP copy-paste detector

PHPCPD is a tool that help us find duplicated code in our codebase. It is extremely helpful on keeping our code DRY. To install it:

1
2
sudo pear config-set auto_discover 1
sudo pear install pear.phpunit.de/phpcpd

Using it is very simple, you just need to specify the project folder to analyze:

1
phpcpd application/

PHP Documentor

Creating code documentation is something most programmers hate, but we wish all other programmers did. It has happened to us sometimes that we are new to a code base and we find that there is no documentation for any of the code. This makes the task of understanding what the code does very time consuming. For this reason it is a good idea to enforce the creation of documentation blocks among our code base.

To install PHPDoc:

1
2
sudo pear channel-discover pear.phpdoc.org
sudo pear install phpdoc/phpDocumentor-alpha

And you can use it like this:

1
phpdoc -d application -t docs

Putting it all together

Running all these commands against our PHP project every time we commit something to our repository would be something very inefficient and error prone. For that reason we want to use ant to run all our metrics with a single command.

Ant uses an XML file, by default named build.xml to create rules that will be executed by it. This is the build.xml file for one of my Zend projects:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<project basedir="." name="myapp">
    <target name="build" depends="phpcs,phpmd,phpcpd,phpdoc"/>

    <target name="phpcs" description="Run PHP Code Sniffer">
        <exec executable="phpcs" failonerror="true">
            <arg value="--standard=Zend"/>
            <arg value="application"/>
            <arg value="public/css"/>
        </exec>
    </target>

    <target name="phpmd" description="Run PHP Mess Detector">
        <exec executable="phpmd" failonerror="true">
            <arg value="application"/>
            <arg value="text"/>
            <arg value="codesize,unusedcode,naming"/>
        </exec>
    </target>

    <target name="phpcpd" description="Run PHP copy-paste detector">
        <exec executable="phpcpd" failonerror="true">
            <arg value="application"/>
        </exec>
    </target>

    <target name="phpdoc" description="Run PHPDoc">
        <exec executable="phpdoc" failonerror="true">
            <arg value="-d"/>
            <arg value="application"/>
            <arg value="-t"/>
            <arg value="docs"/>
            <arg value="-i"/>
            <arg value="application/views/,application/layouts/"/>
            <arg value="--force"/>
            <arg value="--template"/>
            <arg value="checkstyle"/>
        </exec>
    </target>
</project>

Now you can just run this command to execute all the static analysis:

1
ant build

Finally you may want to plug this ant job to a CI system so it is executed every time a commit or a deploy is made. I will try to go over that subject in a future post.

[ automation  php  programming  testing  ]
Testing in Rust
Monitoring Kubernetes Resources with Fabric8 Informers
Introduction to CircleCI
Using testify for Golang tests
Unit testing Golang code