Skip to main content

Quality Assurance on PHP projects - PHP_CodeSniffer


PHP_CodeSniffer is probably the most convenient tool out there to analyze your source code and to verify it complies to company policies. Although it's debatable why source code should follow strict guidelines, it's only a matter of time before you discover yourself that it pays off to have a code base that appears to be written by one developer.

The first question you have to ask is what standard are you going to implement. There are several standards already packaged with PHP_CodeSniffer, but are they useful within your company? Maybe you want to extend or override some standards with your own implementation. Do remember, the standards supplied with PHP_CodeSniffer have been negotiated over and over by the developers for ages. So if you want to define your own standards, be warned that it can be a long and tedious track before you can agree on a specific standard.

Installation
Installing PHP_CodeSniffer is easy when using the PEAR framework. Make sure you have installed and upgraded the pear libraries that come with your OS. After that all you need to do as root or Administrator is the following.

user@server: $ pear install PHP_CodeSniffer

Or you can go to the download page of PHP_CodeSniffer and download the source package yourself and install it the way you want it. In most cases, the PEAR installation is a more elegant, easy way to install the tool.

Configuration & Execution
PHP_CodeSnifferdoesn't require much configuration, but you have to decide on which coding standard you want to check the code base.

Standards provided by PHP_CodeSniffer are the following:
  • Zend
  • PEAR
  • PHPCS
  • Squiz
  • MySource
user@server: phpcs --standard=PEAR /path/to/php/sources

But as stated, you can also define your own standard and provide the base path of the repository on command line

user@server: phpcs --standard=/path/to/my/standards /path/to/php/sources

There are a lot of extra options provided with this tool, but let me focus here on the more important ones you might find useful in your day-to-day usage of PHP_CodeSniffer.

Ignoring files and paths
If you have a couple of external libraries or test scripts in your PHP projects, you might want to exclude them because they're not really part of your concerns. Wouldn't it be easy to just exclude them from the analysis? The following command will exclude paths you have no interest in.

user@server: phpcs --standard=PEAR --ignore=*/tests/*,*/library/Zend/*

Output options
Sometimes you require a different report than the default report that covers all information. Maybe you require a simple summary, a blame report, source report or a report formatted in XML or CSV for usage in another tool. It's only one option away.

The summary report:
user@server: phpcs --standard=PEAR --report=summary

The blame report (requires project to be checked out from a Subversion server):
user@server: phpcs --standard=PEAR --report=svnblame

More on these report formats can be found on the documentation pages of PHP_CodeSniffer.

Roundup
Running PHP_CodeSniffer on the command line is a very convenient way to investigate if the source code is following the standards everyone has agreed upon. 


You can also set it as a pre-commit hook for your revision control system, but in my experience it has a negative effect on the productivity of the development team. But it never hurts to try it out and see for yourself if it's a positive step or causes frustrations. A full description on how to set it up for Subversion is explained on the SVN pre-commit page of PHP_CodeSniffer.

When you want to ensure everyone on your team follows the standard policies of your department or company, PHP_CodeSniffer is a great tool to identify where developers need to modify their code so it complies.

 

Comments

  1. I have been looking into setting this up at my workplace - I got as far as starting to design my own standard, but I realized it's a lot of work to deviate and implement your own standard. It would be great if someone made a simple, configurable set of tests that are customizable in a similar way to NetBeans' code formatting (basically, a simple YAML file or something would suffice for my basic needs).

    On the other hand, maybe this means PHPCS isn't the tool I am looking for, if all I want to do is analyze formatting. PHPCS can delve into much more advanced code analysis than the level I currently need.

    ReplyDelete
  2. Nice, I would be interested if there was some good tutorial on setting up small style changes.

    I would not waste time to create entire new standard but maybe change the style little bit to match our preference :)

    Would you recommend any good articles?

    cheers

    Art

    ReplyDelete
  3. Lineke Kerckhoffs-Willems18/7/11 09:29

    Michelangelo,

    Great post. I have been thinkering with CodeSniffer lately and creating my own sniffs and standard. I'm planning to write a blog post about this soon. If anyone is interested in this sooner, ping me on irc (lineke) or twitter (@the_linie)

    ReplyDelete
  4. For the lazy ones, with Zend Framework -Boilerplate (https://github.com/michael-romer/zf-boilerplate) there is a tool available that builds you a full-featured virtual box for development including PHP_CodeSniffer. It has some other cool features in it as well so maybe this is of help to someone.

    ReplyDelete
  5. A quick note. On some Linux distributions, including Fedora, php_codeSniffer can be installed using the distro tools:

    su -c 'yum -y install php-pear-PHP-CodeSniffer'

    And the run from the terminal:

    phpcs --standard="foo" bar.php

    ReplyDelete
  6. I have enjoyed using the Drupal Standards with PHPCS. They are well documented at http://drupal.org/coding-standard. In addition, there is a conversion script that can update code to resolve many common problems. It's been quite helpful with legacy code, and it runs fine as a standalone script. You can find it as coder_format.php in the drupal distribution.

    In addition, PHPCS is a great tool to integrate with a Jenkins build system. I highly recommend looking at http://jenkins-php.org/ for information about integrating phpcs into a build system.

    ReplyDelete
  7. Anonymous18/7/11 17:25

    For a simpler tool (less powerful but easy to configure) you can also have a look at : http://code.google.com/p/phpcheckstyle/

    ReplyDelete
  8. You don't have to keep specifying the standard to use on the command line - I guess you might be doing this here to iterate the point that there is more than one standard to choose from! Anyway, you can set a standard as the default one for PHPCS to check with:

    sudo phpcs --config-set default_standard PEAR

    There's a small gotcha here - you don't use an "=" sign when setting a value in your config.

    ReplyDelete
  9. Hi Michelangelo,

    Good thing to point out codesniffer. It's an easy to install/use tool.

    Now lets all decide on one coding standard ;) I keep on having to switch different standards in different projects.

    ReplyDelete
  10. The blame report can also be done in Git (version 1.3) and Hg (trunk) as long as you are within the checked out project.

    ReplyDelete

Post a Comment

Popular posts from this blog

PHP 7 and Apache on macOS Sierra

I posted several talks about compiling PHP from source, but everyone was trying to convince me that a package manager like Homebrew was a more convenient way to install. The purpose of Homebrew is simple: a package manager for macOS that will allow you to set up and install common packages easily and allows you to update frequently using simple commands. I used a clean installation of macOS Sierra to ensure all steps could be recorded and tested. In most cases you already have done work on your Mac, so chances are you can skip a few steps in this tutorial. APACHE AND PHP WITH HOMEBREW I’ve made this according to the installation instructions given on GetGrav. The installation procedures These installation procedures will set up your macOS Sierra with PHP 7.1 and Apache 2.4. Install Xcode command line tools (if not done yet)xcode-select --install Install Homebrew/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" Set up for in…

Sessions in PHP 7.1 and Redis

In case you have missed it, PHP 7.1.0 has been released recently. Now you can’t wait to upgrade your servers to the latest and greatest PHP version ever. But hold that thought a second… With PHP 7 lots of things have changed underneath the hood. But these changed features can also put unexpected challenges on your path. Our challenge One of these challenges that we faced was getting PHP 7.1 to play nice storing sessions in our Redis storage. In order to store sessions in Redis, we needed to install the Redis PHP extension that not only provides PHP functions for Redis, but also installs the PHP session handler for Redis. Because we upgraded our servers to PHP 7.1, we were looking to use the latest provided version for this Redis extension: redis-3.1.0. Once installed, we bumped against a nasty problem. Warning: session_start(): Failed to read session data: redis (path: tcp://127.0.0.1:6379) Searching the internet for this error, we didn’t got many hits that could point us into a dire…

Speeding up database calls with PDO and iterators

When you review lots of code, you often wonder why things were written the way they were. Especially when making expensive calls to a database, I still see things that could and should be improved.
No framework development When working with a framework, mostly these database calls are optimized for the developer and abstract the complex logic to improve and optimize the retrieval and usage of data. But then developers need to build something without a framework and end up using the basics of PHP in a sub-optimal way.

$pdo = new \PDO( $config['db']['dsn'], $config['db']['username'], $config['db']['password'] ); $sql = 'SELECT * FROM `gen_contact` ORDER BY `contact_modified` DESC'; $stmt = $pdo->prepare($sql); $stmt->execute(); $data = $stmt->fetchAll(\PDO::FETCH_OBJ); echo 'Getting the contacts that changed the last 3 months' . PHP_EOL; foreach ($data as $row) { $dt = new \DateTime('2015-04-…