Enforcing a PHP coding standard using PHP_CodeSniffer – Part 2

Welcome back to this thrilling trilogy! You have arrived at part 2, and today I’m gonna show you how to use some of the many predefined sniffs included in the PHP_CodeSniffer package to make a shiny “new” coding standard! If you haven’t read the first part of this series I suggest you do so right away.

The coding standard we will implement is by no means a complete standard, but it will be a start and you will probably be able to take it further and define some more rules to make it more complete. The standard I will introduce is a subset of the one that Mats and myself are currently using on a secret world-domination project. I’ll define some rules on how to write control structures (if, for, while, foreach, …), some rules on how to write classes and some other nitpickery like:

  • Disallow short open tag (<?)
  • Max length on the lines in all source files
  • No tabs for indenting

All this can be accomplished by using only predefined sniff classes in the different standards from the PHP_CodeSniffer package.

First we’ll take a look at the package and see how it is structured so we know where to find all the sniffs that I’m constantly ranting about.

After unpacking the PHP_CodeSniffer package we enter the CodeSniffer directory and then the Standards directory. There we find the following directories:

  • Generic
  • MySource
  • PEAR
  • PHPCS
  • Squiz
  • Zend

These are all different coding standards that define different sniff classes. Most of these standards use sniffs from other standards as well. If we enter the Zend directory we will find a script called ZendCodingStandard.php that defines the Zend standard. This class only contains one method called getIncludedSniffs that includes sniffs from other standards. If we define a standard with only custom sniffs the class does not need to implement any methods at all.

In the same directory as the class script we see a directory called Sniffs that includes the sniff classes for the current standard. The structure inside the Sniff directory is up to the developer. The only thing we need to ensure is that all scripts containing a sniff class ends in Sniff.php and that the class is named after the file and directory it is in. Example you ask?

In the Sniffs directory in the Zend standard we have three new directories: Debug, Files and NamingConventions. Inside the Files directory we have a couple of sniffs classes. One of them is called LineLengthSniff.php. The class inside this directory is named: Zend_Sniffs_Files_LineLengthSniff. The naming scheme goes something like: <standard>_Sniffs_<optional directory>_<name of sniff>.php.

Now, let’s create our own standard!

The first thing we need to do is to create a directory for our standard inside the Standards directory. Let’s just call it “MyStandard”. Inside this directory we need to create a class for our standard. Name the file MyStandardCodingStandard.php and open it in an editor and create a class for the standard:

DisallowShortOpenTagSniff.php in the Generic standard. Just what we need! To include sniffs from other standards we will need to add a method called getIncludedSniffs to our class. That method will simply return the sniffs we want to use from other standards. Lets add the DisallowShortOpenTagSniff sniff:

script.php that includes a short open tag. Make something like:

FILE: /path/to/script.php ——————————————————————————– FOUND 1 ERROR(S) AND 0 WARNING(S) AFFECTING 1 LINE(S) ——————————————————————————– 1 | ERROR | Short PHP opening tag used. Found “<?” Expected “<?php”. ——————————————————————————–

Fix the problem and run the test again and you will not get any output, which means everything looks fine. If you get an error when trying to run the command above be sure to change the path to the php bin if it placed somewhere alse, and be sure that the path to the script.php is correct as well.

Lets add some more sniffs to get a more complete standard.

FILE: /path/to/script.php ——————————————————————————– FOUND 7 ERROR(S) AND 1 WARNING(S) AFFECTING 7 LINE(S) ——————————————————————————– 1 | ERROR | Short PHP opening tag used. Found “<?” Expected “<?php”. 2 | WARNING | Line exceeds 80 characters; contains 91 characters 3 | ERROR | Line exceeds maximum limit of 100 characters; contains 136 | | characters 5 | ERROR | Opening brace of a class must be on the line after the | | definition 7 | ERROR | Spaces must be used to indent lines; tabs are not allowed 7 | ERROR | Expected “if (…) {\n”; found “if (…)\n {\n” 8 | ERROR | Spaces must be used to indent lines; tabs are not allowed 11 | ERROR | Expected “} else {\n”; found “}\n else\n {\n” ——————————————————————————–

The errors are pretty self explanatory. The only problem here is that the standard we want to make defines control structures to be written just as we have done in script.php. To be able to fix this we need to extend the PEAR_Sniffs_ControlStructures_ControlSignatureSniff class and edit the regular expressions so they fit our standard. This, and more, in the last and final part of this series which I will try to publish within a week!

Advertisements
This entry was posted in PHP, Technology and tagged , , , , , , . Bookmark the permalink.

12 Responses to Enforcing a PHP coding standard using PHP_CodeSniffer – Part 2

  1. Alex says:

    Brilliant!
    It’s very intimidating looking at the standards files without knowing what’s going on, so thanks for the guide :)

    Looking forward to part 3

  2. Pingback: Bookmarks about Scripts

  3. Larry Zoumas says:

    This is brilliant stuff!

    One problem that threw me a bit in the tutrial…

    The line

    /usr/bin/php /path/to/PHP_CodeSniffer/scripts/phpcs –standard=MyStandard /path/to/script.php

    should actually be

    /usr/bin/php /path/to/PHP_CodeSniffer/scripts/phpcs –-standard=MyStandard /path/to/script.php

    note the double — before standard

    Now I am off to make my own standard!

  4. christer says:

    @Larry: I believe it is wordpress that does that. In the editor I have two dashes, but it is rendered as one. Thanks for pointing that out! Also thanks for reminding me to finish the third part of this series! :)

  5. Amit Shah says:

    This is brilliant stuff and good article.

    Thanks

  6. guillaume says:

    hello,
    is it possible to make structure like this :

    if(…)
    {
    // do something
    }

    succeed to tests?

    thank you

  7. alex says:

    am new member i like php codes but am beginner i hope if helped me 2 go on thanx

  8. Pingback: Cgi script installation service

  9. It’s really a nice and helpful piece of info.
    I am happy that you just shared this useful info with
    us. Please keep us up to date like this.
    Thank you for sharing.

  10. Tabatha says:

    If you are going for best contents like myself, just go to see
    this web page daily for the reason that it presents quality contents, thanks

  11. Pingback: official dragon pharma

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s