Squiz Labs Blog - The latest news from the R&D division of Squiz®

Subscribe to our RSS feeds

PHP_CodeSniffer 1.4.1 released

PHP_CodeSniffer version 1.4.1 has just been uploaded to PEAR and is now available to install. This release includes a few important changes for developers who maintain their own standards and sniffs.

Ignore Patterns

In version 1.3.6, ignore patterns were changed so that they are checked against the relative path of a file instead of the absolute path. This change was done to allow standards to define ignore patterns that didn't have to assume where the code was installed. But there were only very specific cases where using relative paths was better than absolute paths, and all existing ignore patterns needed to be checked to ensure they still worked. Some didn't, and I felt that was important enough to revert the change.

So from version 1.4.1, ignore patterns are now checked against the absolute path of a file again. If you need the ability to check an ignore pattern against the relative path of a file, you can specify this in the ruleset.xml file:

<!--
    Patterns can be specified as relative if you would
    like the relative path of the file checked instead of the
    full path. This can sometimes help with portability.

    The relative path is determined based on the paths you
    pass into PHP_CodeSniffer on the command line.
-->
<exclude-pattern type="relative">^/tests/*</exclude-pattern>
<exclude-pattern type="relative">^/data/*</exclude-pattern>

The T_INLINE_ELSE Token

Natively, PHP doesn't tokenize the question mark or colon in an inline IF statement as a special type of token. PHP_CodeSniffer has always converted the question mark into a token called T_INLINE_THEN but it has always left the colon as T_COLON. Sniffs that look for inline IF statements typically look for the T_INLINE_THEN token and then look ahead for a T_COLON to find the ELSE component.

But now, the colon in an inline IF statement is tokenized as T_INLINE_ELSE. For example:

<?php
$foo = ($bar === true ? 'yes' : 'no');

Will tokenize as:

Process token 0 on line 1 [lvl:0;]: T_OPEN_TAG => <?php\n
Process token 1 on line 2 [lvl:0;]: T_VARIABLE => $foo
Process token 2 on line 2 [lvl:0;]: T_WHITESPACE =>  
Process token 3 on line 2 [lvl:0;]: T_EQUAL => =
Process token 4 on line 2 [lvl:0;]: T_WHITESPACE =>  
Process token 5 on line 2 [lvl:0;]: T_OPEN_PARENTHESIS => (
Process token 6 on line 2 [lvl:0;]: T_VARIABLE => $bar
Process token 7 on line 2 [lvl:0;]: T_WHITESPACE =>  
Process token 8 on line 2 [lvl:0;]: T_IS_IDENTICAL => ===
Process token 9 on line 2 [lvl:0;]: T_WHITESPACE =>  
Process token 10 on line 2 [lvl:0;]: T_TRUE => true
Process token 11 on line 2 [lvl:0;]: T_WHITESPACE =>  
Process token 12 on line 2 [lvl:0;]: T_INLINE_THEN => ?
Process token 13 on line 2 [lvl:0;]: T_WHITESPACE =>  
Process token 14 on line 2 [lvl:0;]: T_CONSTANT_ENCAPSED_STRING => 'yes'
Process token 15 on line 2 [lvl:0;]: T_WHITESPACE =>  
Process token 16 on line 2 [lvl:0;]: T_INLINE_ELSE => :
Process token 17 on line 2 [lvl:0;]: T_WHITESPACE =>  
Process token 18 on line 2 [lvl:0;]: T_CONSTANT_ENCAPSED_STRING => 'no'
Process token 19 on line 2 [lvl:0;]: T_CLOSE_PARENTHESIS => )
Process token 20 on line 2 [lvl:0;]: T_SEMICOLON => ;
Process token 21 on line 2 [lvl:0;]: T_WHITESPACE => \n

Existing sniffs will need to be modified to ensure they work correctly.

Changing the Type of Messages

A problem coding standard developers used to face was that messages could not be changed from errors to warnings, or from warnings to errors. This meant that a new sniff had to be written, or they'd have to live with the existing one, even though it didn't match their coding standard. Sometimes severity levels could be used to work around the problem. But version 1.4.1 now allows you to change the type of any message:

<!--
    You can also change the type of a message from error to
    warning and vice versa.
-->
<rule ref="Generic.Commenting.Todo.CommentFound">
  <type>error</type>
</rule>
<rule ref="Squiz.Strings.DoubleQuoteUsage.ContainsVar">
  <type>warning</type>
</rule>

Mixed Line Endings

PHP_CodeSniffer has trouble tokenizing files that contain mixed line endings. The newline character that is found at the end of the first line is used throughout the tokenizing process to save a lot of processing time, but this may result in line endings being missed. Even the PHP tokenizer can give mixed results when the line endings do not match, although you are unlikely to see any errors on the screen. If processing JS code, you are more likely to see PHP notices from sniffs that get confused.

In version 1.4.1, a special internal warning is added to every file that contains mixed line endings. The warning lets you know that PHP_CodeSniffer may have problems checking that file. It wont stop  all the PHP notices from being shown, but it will at least tell you why they are there. And for continuous integration systems that hide the notices, you'll get a notification in the error report so you are informed.

This warning has the code Internal.LineEndings.Mixed and can be overriden in a ruleset.xml file in the same way the Internal.NoCodeFound message can be. This allows you to change the message, the type to an error or hide it completely by setting the severity to 0.

Everything Else

Apart from these changes, a lot of work has gone into testing and fixing issues with the new PSR-1 and PSR-2 standards that were released in version 1.4.0.

Special thanks to the 5 developers who directly contributed code to this branch. Your help and contributions are always very much appreciated.

You can view the full changelog on the PHP_CodeSniffer download page.

Stay up to date on all PHP_CodeSniffer changes, including new features and releases, by subscribing to the RSS feed or following me on Twitter.

Squiz Labs

R & D division of Squiz Pty Ltd

Open source web experience management solutions

Squiz Labs is the research and development division of Squiz, the company behind the Squiz Suite of web experience management and development tools.

Our PHP and JavaScript developers are responsible for producing innovative enterprise-quality software while our interface designers and testing team ensure our products both look great and are easy to use.