Home » PHP » PHP_CodeSniffer » Manual
PHP_CodeSniffer is a PHP5 script that tokenises and "sniffs" PHP, JavaScript and CSS files to detect violations of a defined coding standard. It is an essential development tool that ensures your code remains clean and consistent. It can also help prevent some common semantic errors made by developers.
Introduction
Introduction – Description and simple usage example
Description
PHP_CodeSniffer is a PHP5 script that tokenises and "sniffs" PHP, JavaScript and CSS files to detect violations of a defined coding standard. It is an essential development tool that ensures your code remains clean and consistent. It can also help prevent some common semantic errors made by developers.
A coding standard in PHP_CodeSniffer is a collection of sniff files. Each sniff file checks one part of the coding standard only. Multiple coding standards can be used within PHP_CodeSniffer so that the one installation can be used across multiple projects. The default coding standard used by PHP_CodeSniffer is the PEAR coding standard.
Example
To check a file against the PEAR coding standard, simply specify the file's location.
Checking a file with PHP_CodeSniffer
$ phpcs /path/to/code/myfile.php
FILE: /path/to/code/myfile.php
--------------------------------------------------------------------------------
FOUND 5 ERROR(S) AFFECTING 2 LINE(S)
--------------------------------------------------------------------------------
2 | ERROR | Missing file doc comment
20 | ERROR | PHP keywords must be lowercase; expected "false" but found "FALSE"
47 | ERROR | Line not indented correctly; expected 4 spaces but found 1
51 | ERROR | Missing function doc comment
88 | ERROR | Line not indented correctly; expected 9 spaces but found 6
--------------------------------------------------------------------------------
Or, if you wish to check an entire directory, you can specify the directory location instead of a file.
Checking a directory with PHP_CodeSniffer
$ phpcs /path/to/code
FILE: /path/to/code/myfile.php
--------------------------------------------------------------------------------
FOUND 5 ERROR(S) AFFECTING 5 LINE(S)
--------------------------------------------------------------------------------
2 | ERROR | Missing file doc comment
20 | ERROR | PHP keywords must be lowercase; expected "false" but found "FALSE"
47 | ERROR | Line not indented correctly; expected 4 spaces but found 1
51 | ERROR | Missing function doc comment
88 | ERROR | Line not indented correctly; expected 9 spaces but found 6
--------------------------------------------------------------------------------
FILE: /path/to/code/yourfile.php
--------------------------------------------------------------------------------
FOUND 1 ERROR(S) AND 1 WARNING(S) AFFECTING 1 LINE(S)
--------------------------------------------------------------------------------
21 | ERROR | PHP keywords must be lowercase; expected "false" but found
| | "FALSE"
21 | WARNING | Equals sign not aligned with surrounding assignments
--------------------------------------------------------------------------------
Requirements
Requirements – A list of software requirements
PHP_CodeSniffer
PHP_CodeSniffer requires PHP version 5.1.2 or greater.
Individual sniffs may have additional requirements, such as external applications and scripts. See the Configuration Options page for a list of these requirements.
SVN pre-commit hook
The pre-commit hook requires PHP version 5.2.4 or greater due to its use of the vertical whitespace character.
Usage
Usage – Standard usage information
Getting Help from the Command Line
Running PHP_CodeSniffer with the -h or --help command line arguments will print a list of commands that PHP_CodeSniffer will respond to. The output of phpcs -h is shown below.
Usage: phpcs [-nwlsapvi] [-d key[=value]]
[--report=<report>] [--report-file=<reportfile>] [--report-<report>=<reportfile>] ...
[--report-width=<reportWidth>] [--generator=<generator>] [--tab-width=<tabWidth>]
[--severity=<severity>] [--error-severity=<severity>] [--warning-severity=<severity>]
[--config-set key value] [--config-delete key] [--config-show]
[--standard=<standard>] [--sniffs=<sniffs>] [--encoding=<encoding>]
[--extensions=<extensions>] [--ignore=<patterns>] <file> ...
-n Do not print warnings (shortcut for --warning-severity=0)
-w Print both warnings and errors (on by default)
-l Local directory only, no recursion
-s Show sniff codes in all reports
-a Run interactively
-p Show progress of the run
-v[v][v] Print verbose output
-i Show a list of installed coding standards
-d Set the [key] php.ini value to [value] or [true] if value is omitted
--help Print this help message
--version Print version information
<file> One or more files and/or directories to check
<extensions> A comma separated list of file extensions to check
(only valid if checking a directory)
<patterns> A comma separated list of patterns to ignore files and directories
<encoding> The encoding of the files being checked (default is iso-8859-1)
<sniffs> A comma separated list of sniff codes to limit the check to
(all sniffs must be part of the specified standard)
<severity> The minimum severity required to display an error or warning
<standard> The name or path of the coding standard to use
<tabWidth> The number of spaces each tab represents
<generator> The name of a doc generator to use
(forces doc generation instead of checking)
<report> Print either the "full", "xml", "checkstyle", "csv", "emacs"
"source", "summary", "svnblame" or "gitblame" report
(the "full" report is printed by default)
<reportfile> Write the report to the specified file path
<reportWidth> How many columns wide screen reports should be printed
The --standard command line argument is optional, even if you have more than one coding standard installed. If no coding standard is specified, PHP_CodeSniffer will default to checking against the PEAR coding standard, or the standard you have set as the default. View instructions for setting the default coding standard.
Checking Files and Folders
The simplest way of using PHP_CodeSniffer is to provide the location of a file or folder for PHP_CodeSniffer to check. If a folder is provided, PHP_CodeSniffer will check all files it finds in that folder and all its sub-folders.
If you do not want sub-folders checked, use the -l command line argument to force PHP_CodeSniffer to run locally in the folders specified.
In the example below, the first command tells PHP_CodeSniffer to check the myfile.inc file for coding standard errors while the second command tells PHP_CodeSniffer to check all PHP files in the my_dir directory.
Checking a single file or folder
$ phpcs /path/to/code/myfile.inc
$ phpcs /path/to/code/my_dir
You can also specify multiple files and folders to check. The command below tells PHP_CodeSniffer to check the myfile.inc file and all files in the my_dir directory.
Checking multiple files and folders
$ phpcs /path/to/code/myfile.inc /path/to/code/my_dir
After PHP_CodeSniffer has finished processing your files, you will get an error report. The report lists both errors and warnings for all files that violated the coding standard. The output looks like this:
Sample PHP_CodeSniffer output
$ phpcs /path/to/code/myfile.php
FILE: /path/to/code/myfile.php
--------------------------------------------------------------------------------
FOUND 5 ERROR(S) AND 1 WARNING(S) AFFECTING 5 LINE(S)
--------------------------------------------------------------------------------
2 | ERROR | Missing file doc comment
20 | ERROR | PHP keywords must be lowercase; expected "false" but found
| | "FALSE"
47 | ERROR | Line not indented correctly; expected 4 spaces but found 1
47 | WARNING | Equals sign not aligned with surrounding assignments
51 | ERROR | Missing function doc comment
88 | ERROR | Line not indented correctly; expected 9 spaces but found 6
--------------------------------------------------------------------------------
If you don't want warnings included in the output, specify the -n command line argument.
Sample PHP_CodeSniffer output with no warnings
$ phpcs -n /path/to/code/myfile.php
FILE: /path/to/code/myfile.php
--------------------------------------------------------------------------------
FOUND 5 ERROR(S) AFFECTING 5 LINE(S)
--------------------------------------------------------------------------------
2 | ERROR | Missing file doc comment
20 | ERROR | PHP keywords must be lowercase; expected "false" but found "FALSE"
47 | ERROR | Line not indented correctly; expected 4 spaces but found 1
51 | ERROR | Missing function doc comment
88 | ERROR | Line not indented correctly; expected 9 spaces but found 6
--------------------------------------------------------------------------------
Printing a Summary Report
By default, PHP_CodeSniffer will print a complete list of all errors and warnings it finds. This list can become quite long, especially when checking a large number of files at once. To print a summary report that only shows the number of errors and warnings for each file, use the --report=summary command line argument. The output will look like this:
Sample PHP_CodeSniffer summary output
$ phpcs --report=summary /path/to/code
PHP CODE SNIFFER REPORT SUMMARY
--------------------------------------------------------------------------------
FILE ERRORS WARNINGS
--------------------------------------------------------------------------------
/path/to/code/myfile.inc 5 0
/path/to/code/yourfile.inc 1 1
/path/to/code/ourfile.inc 0 2
--------------------------------------------------------------------------------
A TOTAL OF 6 ERROR(S) AND 3 WARNING(S) WERE FOUND IN 3 FILE(S)
--------------------------------------------------------------------------------
As with the full report, you can suppress the printing of warnings with the -n command line argument.
Sample PHP_CodeSniffer summary output with no warnings
$ phpcs -n --report=summary /path/to/code
PHP CODE SNIFFER REPORT SUMMARY
--------------------------------------------------------------------------------
FILE ERRORS
--------------------------------------------------------------------------------
/path/to/code/myfile.inc 5
/path/to/code/yourfile.inc 1
--------------------------------------------------------------------------------
A TOTAL OF 6 ERROR(S) WERE FOUND IN 2 FILE(S)
--------------------------------------------------------------------------------
Printing Progress Information
By default, PHP_CodeSniffer will run quietly, only printing the report of errors and warnings at the end. If you are checking a large number of files, you may have to wait a while to see the report. If you want to know what is happening, you can turn on progress or verbose output.
With progress output enabled, PHP_CodeSniffer will print a single-character status for each file being checked. The possible status characters are:
.: The file contained no errors or warningsE: The file contained 1 or more errorsW: The file contained 1 or more warnings, but no errorsS: The file contained a @codingStandardsIgnoreFile comment and was skipped
Progress output will look like this:
Sample PHP_CodeSniffer progress output
$ phpcs /path/to/code/CodeSniffer -p
......................S..................................... 60 / 572
..........EEEE.E.E.E.E.E.E.E.E..W..EEE.E.E.E.EE.E.E.E.E.E.E. 120 / 572
E.E.E.E.E.WWWW.E.W..EEE.E.................E.E.E.E...E....... 180 / 572
E.E.E.E.....................E.E.E.E.E.E.E.E.E.E.W.E.E.E.E.E. 240 / 572
E.W......................................................... 300 / 572
..........................................E.E.E.E...E.E.E.E. 360 / 572
E.E.E.E.E.E..E.E.E..E..E..E.E.WW.E.E.EE.E.E................. 420 / 572
...................E.E.EE.E.E.E.S.E.EEEE.E...E...EE.E.E..EEE 480 / 572
.E.EE.E.E..E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E..E..E..E.E.E..E 540 / 572
.E.E....E.E.E...E.....E.E.ES....
You can configure PHP_CodeSniffer to show progress information by default using the configuration option.
With verbose output enabled, PHP_CodeSniffer will print the file that it is checking, show you how many tokens and lines the file contains, and let you know how long it took to process. The output will look like this:
Sample PHP_CodeSniffer verbose output
$ phpcs /path/to/code/CodeSniffer -v
Registering sniffs in PEAR standard... DONE (24 sniffs registered)
Creating file list... DONE (572 files in queue)
Processing AbstractDocElement.php [1093 tokens in 303 lines]... DONE in < 1 second (0 errors, 1 warnings)
Processing AbstractParser.php [2360 tokens in 558 lines]... DONE in 2 seconds (0 errors, 1 warnings)
Processing ClassCommentParser.php [923 tokens in 296 lines]... DONE in < 1 second (2 errors, 0 warnings)
Processing CommentElement.php [988 tokens in 218 lines]... DONE in < 1 second (1 error, 5 warnings)
Processing FunctionCommentParser.php [525 tokens in 184 lines]... DONE in 1 second (0 errors, 6 warnings)
Processing File.php [10968 tokens in 1805 lines]... DONE in 5 seconds (0 errors, 5 warnings)
Processing Sniff.php [133 tokens in 94 lines]... DONE in < 1 second (0 errors, 0 warnings)
Processing SniffException.php [47 tokens in 36 lines]... DONE in < 1 second (1 errors, 3 warnings)
Specifying a Coding Standard
PHP_CodeSniffer can have multiple coding standards installed to allow a single installation to be used with multiple projects. When checking PHP code, PHP_CodeSniffer can be told which coding standard to use. This is done using the --standard command line argument.
The example below checks the myfile.inc file for violations of the PEAR coding standard (installed by default).
Specifying a coding standard to use
$ phpcs --standard=PEAR /path/to/code/myfile.inc
Can you also tell PHP_CodeSniffer to use an external standard by specifying the full path to the standard's root directory on the command line. An external standard is one that is stored outside of PHP_CodeSniffer'sStandardsdirectory.Specifying an external coding standard
$ phpcs --standard=/path/to/MyStandard /path/to/code/myfile.inc
Printing a List of Installed Coding Standards
PHP_CodeSniffer can print you a list of the coding standards that are installed so that you can correctly specify a coding standard to use for testing. You can print this list by specifying the -i command line argument.
Generating a list of installed coding standards
$ phpcs -i
The installed coding standards are Zend, PEAR, PHPCS, Squiz and MySource
Advanced Usage
Advanced Usage – Advanced usage information
Specifying Valid File Extensions
By default, PHP_CodeSniffer will check any file it finds with a .inc or .php extension. Sometimes, this means that PHP_CodeSniffer is not checking enough of your files. Sometimes, the opposite is true. PHP_CodeSniffer allows you to specify a list of valid file extensions using the --extensions command line argument. Extensions are separated by commas.
Checking .php files only
$ phpcs --extensions=php /path/to/code
Checking .php, .inc and .lib files only
$ phpcs --extensions=php,inc,lib /path/to/code
If you have asked PHP_CodeSniffer to check a specific file rather than an entire directory, the extension of the specified file will be ignored. The file will be checked even if it has an invalid extension or no extension at all. In the following example, the main.inc file will be checked by PHP_CodeSniffer even though the--extensionscommand line argument specifies that only.phpfiles should be checked.Extension ignored when checking specific file
$ phpcs --extensions=php /path/to/code/main.inc
The ignoring of file extensions for specific files is a feature of PHP_CodeSniffer and is the only way to check files without an extension. If you check an entire directory of files, all files without extensions will be ignored, so you must check each of these file separately.
Ignoring Files and Folders
Sometimes you want PHP_CodeSniffer to run over a very large number of files, but you want some files and folders to be skipped. The --ignore command line argument can be used to tell PHP_CodeSniffer to skip files and folders that match one or more patterns.
In the following example, PHP_CodeSniffer will skip all files inside the package's tests and data directories. This is useful if you are checking a PEAR package but don't want your test or data files to conform to your coding standard.
Ignoring test and data files
$ phpcs --ignore=*/tests/*,*/data/* /path/to/code
You can also tell PHP_CodeSniffer to ignore a file using a special comment inserted at the top of the file. This will stop the file being checked even if it does not match the ignore pattern.Ignoring a file using a comment
<?php
// @codingStandardsIgnoreFile
$xmlPackage = new XMLPackage;
$xmlPackage['error_code'] = get_default_error_code_value();
$xmlPackage->send();
?>
Ignoring Parts of a File
Some parts of your code may be unable to conform to your coding standard. For example, you might have to break your standard to integrate with an external library or web service. To stop PHP_CodeSniffer generating errors for this code, you can wrap it in special comments. PHP_CodeSniffer will then hide all errors and warnings that are generated for these lines of code.
Ignoring parts of a file using comments
$xmlPackage = new XMLPackage;
// @codingStandardsIgnoreStart
$xmlPackage['error_code'] = get_default_error_code_value();
// @codingStandardsIgnoreEnd
$xmlPackage->send();
Limiting Results to Specific Sniffs
By default, PHP_CodeSniffer will check your code using all sniffs in the specified standard. Sometimes you may want to find all occurrences of an error to eliminate it more quickly or understand the scope of the problem. PHP_CodeSniffer allows you to specify a list of sniffs to limit results to using the --sniffs command line argument. Sniffs are separated by commas.
Checking files for two specific sniffs only
$ phpcs --standard=PEAR --sniffs=Generic.PHP.LowerCaseConstant,PEAR.WhiteSpace.ScopeIndent /path/to/code
This feature is a message filter and not a quick way to define a custom coding standard. All sniffs specified on the command line in this way must be used in the coding standard you are using to check your files. You can't, for example, limit results to Squiz sniffs while using the PEAR standard as the PEAR standard does not include these sniffs.
To view source codes for error messages, use the -s command line argument. This will print source codes in the full, summary and source reports.
Filtering Errors and Warnings Based on Severity
By default, PHP_CodeSniffer assigns a severity of 5 to all errors and warnings. Standards, especially custom standards, may change the severity of some messages so they are hidden by default or even so that they are raised to indicate greater importance. PHP_CodeSniffer allows you to decide what the minimum severity level must be to show a message in its report using the --severity command line argument.
Hiding errors and warnings with a severity less than 3
$ phpcs --severity=3 /path/to/code
You can specify different values for errors and warnings using the --error-severity and --warning-severity command line arguments.
Showing all errors but only warnings with a severity of 8 or more
$ phpcs --error-severity=1 --warning-severity=8 /path/to/code
Setting the severity of warnings to0is the same as using the-ncommand line argument. If you set the severity of errors to0PHP_CodeSniffer will not show any errors, which may be useful if you just want to show the warnings.
This feature is particularly useful during manual code reviews. During normal development or an automated build, you may want to only check code formatting issues while during a code review you may wish to show less severe errors and warnings that may need manual peer review.
Replacing Tabs with Spaces
Most of the sniffs written for PHP_CodeSniffer do not support the usage of tabs for indentation and alignment. You can write your own sniffs that check for tabs instead of spaces, but you can also get PHP_CodeSniffer to convert your tabs into spaces before a file is checked. This allows you to use the existing space-based sniffs on your tab-based files.
In the following example, PHP_CodeSniffer will replace all tabs in the files being checked with between 1 and 4 spaces, depending on the column the tab indents to.
Converting tabs to spaces
$ phpcs --tab-width=4 /path/to/code
Specifying an Encoding
Some PHP_CodeSniffer reports output UTF-8 encoded XML, which can cause problems if your files are already UTF-8 encoded. In this case, some content from your files (generally comments) are used within error messages and may be double-encoded. To help PHP_CodeSniffer encode reports correctly, you can specify the encoding of your source files using the --encoding command line argument.
Specifying UTF-8 encoding
$ phpcs --encoding=utf-8 /path/to/code
The default encoding used by PHP_CodeSniffer is ISO-8859-1.
Specifying php.ini Settings
PHP_CodeSniffer allows you to set temporary php.ini settings during a run using the -d command line argument. The name of the php.ini setting must be specified on the command line, but the value is optional. If no value is set, the php.ini setting will be given a value of TRUE.
Specifying a memory limit
$ phpcs -d memory_limit=32M /path/to/code
Specifying multiple values
$ phpcs -d memory_limit=32M -d include_path=.:/php/includes /path/to/code
Setting Configuration Options
PHP_CodeSniffer has some configuration options that can be set. Individual coding standards may also require configuration options to be set before functionality can be used. View a full list of configuration options.
To set a configuration option, use the --config-set command line argument.
Setting a configuration option
$ phpcs --config-set <option> <value>
Deleting Configuration Options
PHP_CodeSniffer allows you to delete any configuration option, reverting it to its default value. View a full list of configuration options.
To delete a configuration option, use the --config-delete command line argument.
Deleting a configuration option
$ phpcs --config-delete <option>
Viewing Configuration Options
To view the currently set configuration options, use the --config-show command line argument.
Viewing configuration options
$ phpcs --config-show
Array
(
[default_standard] => PEAR
[zend_ca_path] => /path/to/ZendCodeAnalyzer
)
Printing Verbose Tokeniser Output
This feature is provided for debugging purposes only. Using this feature will dramatically increase screen output and script running time.
PHP_CodeSniffer contains multiple verbosity levels. Level 2 (indicated by the command line argument -vv) will print all verbosity information for level 1 (file specific token and line counts with running times) as well as verbose tokeniser output.
The output of the PHP_CodeSniffer tokeniser shows the step-by-step creation of the scope map and the level map.
The Scope Map
The scope map is best explained with an example. For the following file:
<?php
if ($condition) {
echo 'Condition was true';
}
?>
The scope map output is:
Sample scope map output
*** START SCOPE MAP ***
Start scope map at 1: T_IF => if
Process token 2 []: T_WHITESPACE =>
Process token 3 []: T_OPEN_PARENTHESIS => (
Process token 6 []: T_WHITESPACE =>
Process token 7 []: T_OPEN_CURLY_BRACKET => {
=> Found scope opener for 1 (T_IF)
Process token 8 [opener:7;]: T_WHITESPACE => \n
Process token 9 [opener:7;]: T_WHITESPACE =>
Process token 10 [opener:7;]: T_ECHO => echo
Process token 11 [opener:7;]: T_WHITESPACE =>
Process token 12 [opener:7;]: T_CONSTANT_ENCAPSED_STRING => 'Condition was true'
Process token 13 [opener:7;]: T_SEMICOLON => ;
Process token 14 [opener:7;]: T_WHITESPACE => \n
Process token 15 [opener:7;]: T_CLOSE_CURLY_BRACKET => }
=> Found scope closer for 1 (T_IF)
*** END SCOPE MAP ***
The scope map output above shows the following pieces of information about the file:
-
A scope token,
if, was found at token 1 (note that token 0 is the open PHP tag). -
The opener for the
ifstatement, the open curly brace, was found at token 7. -
The closer for the
ifstatement, the close curly brace, was found at token 15. -
Tokens 8 - 15 are all included in the scope set by the scope opener at token 7, the open curly brace. This indicates that these tokens are all within the
ifstatement.
The scope map output is most useful when debugging PHP_CodeSniffer's scope map, which is critically important to the successful checking of a file, but is also useful for checking the type of a particular token. For example, if you are unsure of the token type for an opening curly brace, the scope map output shows you that the type is T_OPEN_CURLY_BRACKET and not, for example, T_OPEN_CURLY_BRACE.
The Level Map
The level map is best explained with an example. For the following file:
<?php
if ($condition) {
echo 'Condition was true';
}
?>
The level map output is:
Sample level map output
*** START LEVEL MAP ***
Process token 0 on line 1 [lvl:0;]: T_OPEN_TAG => <?php\n
Process token 1 on line 2 [lvl:0;]: T_IF => if
Process token 2 on line 2 [lvl:0;]: T_WHITESPACE =>
Process token 3 on line 2 [lvl:0;]: T_OPEN_PARENTHESIS => (
Process token 4 on line 2 [lvl:0;]: T_VARIABLE => $condition
Process token 5 on line 2 [lvl:0;]: T_CLOSE_PARENTHESIS => )
Process token 6 on line 2 [lvl:0;]: T_WHITESPACE =>
Process token 7 on line 2 [lvl:0;]: T_OPEN_CURLY_BRACKET => {
=> Found scope opener for 1 (T_IF)
* level increased *
* token 1 (T_IF) added to conditions array *
Process token 8 on line 2 [lvl:1;conds;T_IF;]: T_WHITESPACE => \n
Process token 9 on line 3 [lvl:1;conds;T_IF;]: T_WHITESPACE =>
Process token 10 on line 3 [lvl:1;conds;T_IF;]: T_ECHO => echo
Process token 11 on line 3 [lvl:1;conds;T_IF;]: T_WHITESPACE =>
Process token 12 on line 3 [lvl:1;conds;T_IF;]: T_CONSTANT_ENCAPSED_STRING => 'Condition was true'
Process token 13 on line 3 [lvl:1;conds;T_IF;]: T_SEMICOLON => ;
Process token 14 on line 3 [lvl:1;conds;T_IF;]: T_WHITESPACE => \n
Process token 15 on line 4 [lvl:1;conds;T_IF;]: T_CLOSE_CURLY_BRACKET => }
=> Found scope closer for 7 (T_OPEN_CURLY_BRACKET)
* token T_IF removed from conditions array *
* level decreased *
Process token 16 on line 4 [lvl:0;]: T_WHITESPACE => \n
Process token 17 on line 5 [lvl:0;]: T_CLOSE_TAG => ?>\n
*** END LEVEL MAP ***
The level map output above shows the following pieces of information about the file:
-
A scope opener, an open curly brace, was found at token 7 and opened the scope for an
ifstatement, defined at token 1. -
Tokens 8 - 15 are all included in the scope set by the scope opener at token 7, the open curly brace. All these tokens are at level 1, indicating that they are enclosed in 1 scope condition, and all these tokens are enclosed in a single condition; an
ifstatement.
The level map is most commonly used to determine indentation rules (e.g., a token 4 levels deep requires 16 spaces of indentation) or to determine if a particular token is within a particular scope (eg. a function keyword is within a class scope, making it a method).
Printing Verbose Token Processing Output
This feature is provided for debugging purposes only. Using this feature will dramatically increase screen output and script running time.
PHP_CodeSniffer contains multiple verbosity levels. Level 3 (indicated by the command line argument -vvv) will print all verbosity information for level 1 (file specific token and line counts with running times), level 2 (tokeniser output) as well as token processing output with sniff running times.
The token processing output is best explained with an example. For the following file:
<?php
if ($condition) {
echo 'Condition was true';
}
?>
The token processing output is:
Sample token processing output
*** START TOKEN PROCESSING ***
Process token 0: T_OPEN_TAG => <?php\n
Processing PEAR_Sniffs_Commenting_FileCommentSniff... DONE in 0.001 seconds
Processing PEAR_Sniffs_Files_LineLengthSniff... DONE in 0.0004 seconds
Processing PEAR_Sniffs_PHP_DisallowShortOpenTagSniff... DONE in 0.0001 seconds
Process token 1: T_IF => if
Processing PEAR_Sniffs_ControlStructures_ControlSignatureSniff... DONE in 0.0008 seconds
Processing PEAR_Sniffs_WhiteSpace_ScopeClosingBraceSniff... DONE in 0.0248 seconds
Processing PEAR_Sniffs_WhiteSpace_ScopeIndentSniff... DONE in 0.0004 seconds
Process token 2: T_WHITESPACE =>
Process token 3: T_OPEN_PARENTHESIS => (
Process token 4: T_VARIABLE => $condition
Process token 5: T_CLOSE_PARENTHESIS => )
Process token 6: T_WHITESPACE =>
Process token 7: T_OPEN_CURLY_BRACKET => {
Process token 8: T_WHITESPACE => \n
Process token 9: T_WHITESPACE =>
Process token 10: T_ECHO => echo
Process token 11: T_WHITESPACE =>
Process token 12: T_CONSTANT_ENCAPSED_STRING => 'Condition was true'
Process token 13: T_SEMICOLON => ;
Process token 14: T_WHITESPACE => \n
Process token 15: T_CLOSE_CURLY_BRACKET => }
Process token 16: T_WHITESPACE => \n
Process token 17: T_CLOSE_TAG => ?>\n
*** END TOKEN PROCESSING ***
Every token processed is shown, along with its ID, type and contents. For each token, all sniffs that were executed on the token are displayed, along with the running time.
For example, the output above shows us that token 1, an if keyword, had 3 sniffs executed on it; the ControlSignature sniff, the ScopeClosingBrace sniff and the ScopeIndent sniff. Each was executed fairly quickly, but the slowest was the ScopeClosingBrace sniff, taking 0.0248 seconds to process that token.
The other interesting piece of information we get from the output above is that only 2 tokens in the whole file had sniffs executed on them; tokens 0 and 1. This is normal behavior for PHP_CodeSniffer as most sniffs listen for a very specific and rarely used token and then execute on it and a number of tokens following it.
For example, the ScopeIndentSniff executes on the if statement's token only, but actually checks the indentation of every line within the if statement. The sniff uses the scope map to find all tokens within the if statement.
Reporting
Reporting – Report types and options
Printing Full and Summary Reports
See the main Usage page for basic usage information about these report types, including example output.
Both the full and summary reports can additionally show information about the source of errors and warnings. Source codes can be used with the --sniffs command line argument to only show messages from a specified list of sources. To include source codes in the report, use the -s command line argument.
Sample PHP_CodeSniffer full report with source codes
$ phpcs -s /path/to/code/myfile.php
FILE: /path/to/code/myfile.php
--------------------------------------------------------------------------------
FOUND 5 ERROR(S) AND 1 WARNING(S) AFFECTING 5 LINE(S)
--------------------------------------------------------------------------------
2 | ERROR | Missing file doc comment (PEAR.Commenting.FileComment)
20 | ERROR | PHP keywords must be lowercase; expected "false" but found
| | "FALSE" (Generic.PHP.LowerCaseConstant)
47 | ERROR | Line not indented correctly; expected 4 spaces but found 1
| | (PEAR.WhiteSpace.ScopeIndent)
47 | WARNING | Equals sign not aligned with surrounding assignments
| | (Generic.Formatting.MultipleStatementAlignment)
51 | ERROR | Missing function doc comment
| | (PEAR.Commenting.FunctionComment)
88 | ERROR | Line not indented correctly; expected 9 spaces but found 6
| | (PEAR.WhiteSpace.ScopeIndent)
--------------------------------------------------------------------------------
Sample PHP_CodeSniffer summary report with source codes
$ phpcs -s --report=summary /path/to/code
PHP CODE SNIFFER REPORT SUMMARY
--------------------------------------------------------------------------------
FILE ERRORS WARNINGS
--------------------------------------------------------------------------------
/path/to/code/myfile.inc 5 0
/path/to/code/yourfile.inc 1 1
/path/to/code/ourfile.inc 0 2
--------------------------------------------------------------------------------
A TOTAL OF 6 ERROR(S) AND 3 WARNING(S) WERE FOUND IN 3 FILE(S)
--------------------------------------------------------------------------------
PHP CODE SNIFFER VIOLATION SOURCE SUMMARY
--------------------------------------------------------------------------------
SOURCE COUNT
--------------------------------------------------------------------------------
PEAR.WhiteSpace.ScopeIndent 3
PEAR.Commenting.FileComment 2
Generic.PHP.LowerCaseConstant 2
Generic.Formatting.MultipleStatementAlignment 1
PEAR.Commenting.FunctionComment 1
--------------------------------------------------------------------------------
A TOTAL OF 9 SNIFF VIOLATION(S) WERE FOUND IN 5 SOURCE(S)
--------------------------------------------------------------------------------
Printing a Source Report
PHP_CodeSniffer can output a summary report showing you the most common errors detected in your files so you can target specific parts of your coding standard for improvement. To print a source report, use the --report=source command line argument. The output will look like this:
Sample PHP_CodeSniffer source output
$ phpcs --report=source /path/to/code
PHP CODE SNIFFER VIOLATION SOURCE SUMMARY
--------------------------------------------------------------------------------
STANDARD CATEGORY SNIFF COUNT
--------------------------------------------------------------------------------
Generic PHP Lower case constant 4
PEAR White space Scope indent 3
PEAR Commenting File comment 1
--------------------------------------------------------------------------------
A TOTAL OF 8 SNIFF VIOLATION(S) WERE FOUND IN 3 SOURCE(S)
--------------------------------------------------------------------------------
To show source codes instead of friendly names, use the -s command line argument.
Sample PHP_CodeSniffer source code output
$ phpcs -s --report=source /path/to/code
PHP CODE SNIFFER VIOLATION SOURCE SUMMARY
--------------------------------------------------------------------------------
SOURCE COUNT
--------------------------------------------------------------------------------
Generic.PHP.LowerCaseConstant 4
PEAR.WhiteSpace.ScopeIndent 3
PEAR.Commenting.FileComment 1
--------------------------------------------------------------------------------
A TOTAL OF 8 SNIFF VIOLATION(S) WERE FOUND IN 3 SOURCE(S)
--------------------------------------------------------------------------------
Printing an XML Report
PHP_CodeSniffer can output an XML report to allow you to parse the output easily and use the results in your own scripts. To print an XML report, use the --report=xml command line argument. The output will look like this:
Sample PHP_CodeSniffer XML output
$ phpcs --report=xml /path/to/code
<?xml version="1.0" encoding="UTF-8"?>
<phpcs version="1.0.0">
<file name="/path/to/code/myfile.php" errors="4" warnings="1">
<error line="2" column="1" source="PEAR.Commenting.FileComment" severity="5">Missing file doc comment</error>
<error line="20" column="43" source="Generic.PHP.LowerCaseConstant" severity="5">PHP keywords must be lowercase; expected "false" but found "FALSE"</error>
<error line="47" column="1" source="PEAR.WhiteSpace.ScopeIndent" severity="5">Line not indented correctly; expected 4 spaces but found 1</error>
<warning line="47" column="20" source="Generic.Formatting.MultipleStatementAlignment" severity="5">Equals sign not aligned with surrounding assignments</warning>
<error line="51" column="4" source="PEAR.Commenting.FunctionComment" severity="5">Missing function doc comment</error>
</file>
</phpcs>
Printing a Checkstyle Report
PHP_CodeSniffer can output an XML report similar to the one produced by Checkstyle, allowing you to use the output in scripts and applications that already support Checkstyle. To print a Checkstyle report, use the --report=checkstyle command line argument. The output will look like this:
Sample PHP_CodeSniffer Checkstyle output
$ phpcs --report=checkstyle /path/to/code
<?xml version="1.0" encoding="UTF-8"?>
<checkstyle version="1.0.0">
<file name="/path/to/code/myfile.php">
<error line="2" column="1" severity="error" message="Missing file doc comment" source="PEAR.Commenting.FileComment"/>
<error line="20" column="43" severity="error" message="PHP keywords must be lowercase; expected "false" but found "FALSE"" source="Generic.PHP.LowerCaseConstant"/>
<error line="47" column="1" severity="error" message="Line not indented correctly; expected 4 spaces but found 1" source="PEAR.WhiteSpace.ScopeIndent"/>
<error line="47" column="20" severity="warning" message="Equals sign not aligned with surrounding assignments" source="Generic.Formatting.MultipleStatementAlignment"/>
<error line="51" column="4" severity="error" message="Missing function doc comment" source="PEAR.Commenting.FunctionComment"/>
</file>
</checkstyle>
Printing a CSV Report
PHP_CodeSniffer can output a CSV report to allow you to parse the output easily and use the results in your own scripts. To print a CSV report, use the --report=csv command line argument. The output will look like this:
Sample PHP_CodeSniffer CSV output
$ phpcs --report=csv /path/to/code
File,Line,Column,Type,Message,Source,Severity
"/path/to/code/myfile.php",2,1,error,"Missing file doc comment",PEAR.Commenting.FileComment,5
"/path/to/code/myfile.php",20,43,error,"PHP keywords must be lowercase; expected \"false\" but found \"FALSE\"",Generic.PHP.LowerCaseConstant,5
"/path/to/code/myfile.php",47,1,error,"Line not indented correctly; expected 4 spaces but found 1",PEAR.WhiteSpace.ScopeIndent,5
"/path/to/code/myfile.php",47,20,warning,"Equals sign not aligned with surrounding assignments",Generic.Formatting.MultipleStatementAlignment,5
"/path/to/code/myfile.php",51,4,error,"Missing function doc comment",PEAR.Commenting.FunctionComment,5
The first row of the CSV output defines the order of information. When using the CSV output, please parse this header row to determine the order correctly as the format may change over time or new information may be added.
Printing an Emacs Report
PHP_CodeSniffer can output a report in a format the compiler built into the GNU Emacs text editor can understand. This lets you use the built-in complier to run PHP_CodeSniffer on a file you are editing and navigate between errors and warnings within the file. To print an Emacs report, use the --report=emacs command line argument. The output will look like this:
Sample PHP_CodeSniffer Emacs output
$ phpcs --report=emacs /path/to/code
/path/to/code/myfile.php:2:1: error - Missing file doc comment
/path/to/code/myfile.php:20:43: error - PHP keywords must be lowercase; expected "false" but found "FALSE"
/path/to/code/myfile.php:47:1: error - Line not indented correctly; expected 4 spaces but found 1
/path/to/code/myfile.php:47:20: warning - Equals sign not aligned with surrounding assignments
/path/to/code/myfile.php:51:4: error - Missing function doc comment
To use PHP_CodeSniffer with Emacs, make sure you have installed PHP mode for Emacs. Then put the following into your .emacs file, changing PHP_CodeSniffer options as required.
Sample .emacs file
(defun my-php-hook-function ()
(set (make-local-variable 'compile-command) (format "phpcs --report=emacs --standard=PEAR %s" (buffer-file-name))))
(add-hook 'php-mode-hook 'my-php-hook-function)
Now you can use the compile command and associated shortcuts to move between error messages within your file.
Printing an SVN Blame Report
PHP_CodeSniffer can make use of the svn blame command to try and determine who committed each error and warning to an SVN respository. To print an SVN Blame report, use the --report=svnblame command line argument. The output will look like this:
Sample PHP_CodeSniffer SVN Blame output
$ phpcs --report=svnblame /path/to/code
PHP CODE SNIFFER SVN BLAME SUMMARY
--------------------------------------------------------------------------------
AUTHOR COUNT (%)
--------------------------------------------------------------------------------
jsmith 51 (40.8)
jblogs 44 (30)
pdeveloper 43 (10.33)
jscript 27 (19.84)
--------------------------------------------------------------------------------
A TOTAL OF 165 SNIFF VIOLATION(S) WERE COMMITTED BY 4 AUTHOR(S)
--------------------------------------------------------------------------------
Each author is listed with the number of violations they committed and the percentage of error lines to clean lines. The example report above shows that the developer pdeveloper has 43 violations but they only make up 10% of all code they have committed, while jblogs has 44 violations but they make up 30% of all their committed code. So these developers have about the same number of total violations, but pdeveloper seems to be doing a better job of conforming to the coding standard.
To show a breakdown of the types of violations each author is committing, use the -s command line argument.
Sample PHP_CodeSniffer SVN Blame output with sources
$ phpcs -s --report=svnblame /path/to/code
PHP CODE SNIFFER SVN BLAME SUMMARY
--------------------------------------------------------------------------------
AUTHOR SOURCE COUNT (%)
--------------------------------------------------------------------------------
jsmith 51 (40.8)
Squiz.Files.LineLength 47
PEAR.Functions.FunctionCallSignature 4
jblogs 44 (30)
Squiz.Files.LineLength 40
Generic.CodeAnalysis.UnusedFunctionParameter 2
Squiz.CodeAnalysis.EmptyStatement 1
Squiz.Formatting.MultipleStatementAlignment 1
--------------------------------------------------------------------------------
A TOTAL OF 95 SNIFF VIOLATION(S) WERE COMMITTED BY 2 AUTHOR(S)
--------------------------------------------------------------------------------
To include authors with no violations, and perhaps shower them with praise, use the -v command line argument.
Sample PHP_CodeSniffer SVN Blame verbose output
$ phpcs -v --report=svnblame /path/to/code
PHP CODE SNIFFER SVN BLAME SUMMARY
--------------------------------------------------------------------------------
AUTHOR COUNT (%)
--------------------------------------------------------------------------------
jsmith 51 (40.8)
jblogs 44 (30)
pdeveloper 43 (10.33)
jscript 27 (19.84)
toogood 0 (0)
--------------------------------------------------------------------------------
A TOTAL OF 165 SNIFF VIOLATION(S) WERE COMMITTED BY 5 AUTHOR(S)
--------------------------------------------------------------------------------
You need to make sure the location of the svn command is in your path and that SVN is storing a username and password (if required by your repository). If the command is not in your path, the report will fail to generate. If SVN does not have a username and password stored, you'll need to enter it for each file being checked by PHP_CodeSniffer that contains violations.
Printing a Git Blame Report
Like the SVN Blame report, PHP_CodeSniffer can make use of the git blame command to try and determine who committed each error and warning to a Git respository. To print a Git Blame report, use the --report=gitblame command line argument. The output and options are the same as those described in the SVN Blame report above.
You need to make sure the location of the git command is in your path. If the command is not in your path, the report will fail to generate.
Printing Mutliple Reports
PHP_CodeSniffer can print any combination of the above reports to either the screen or to separate files. To print multiple reports, use the --report-[type] command line argument instead of the standard --report=[type] format. You can then specify multiple reports using multiple arguments. The reports will be printed to the screen in the order you specify them on the command line.
Writing a full and summary report to the screen
$ phpcs --report-full --report-summary /path/to/code
You can write the reports to separate files by specifying the path to the output file after each report argument.
Writing a full and summary report to a file
$ phpcs --report-full=/path/to/full.txt --report-summary=/path/to/summary.txt /path/to/code
You can print some reports to the screen and other reports to files.
Writing a full report to a file and a summary report to the screen
$ phpcs --report-full=/path/to/full.txt --report-summary /path/to/code
Running Interactively
Instead of producing a single report at the end of a run, PHP_CodeSniffer can run interactively and show reports for files one at a time. When using the interactive mode, PHP_CodeSniffer will show a report for the first file it finds an error or warning in. It will then pause and wait for user input. Once you have corrected the errors, you can press ENTER to have PHP_CodeSniffer recheck your file and continue if the file is now free of errors. You can also choose to skip the file and move to the next file with errors.
To run PHP_CodeSniffer interactively, use the -a command line argument.
Running interactively
$ phpcs -a /path/to/code
FILE: /path/to/code/myfile.php
--------------------------------------------------------------------------------
FOUND 5 ERROR(S) AND 1 WARNING(S) AFFECTING 5 LINE(S)
--------------------------------------------------------------------------------
2 | ERROR | Missing file doc comment
20 | ERROR | PHP keywords must be lowercase; expected "false" but found
| | "FALSE"
47 | ERROR | Line not indented correctly; expected 4 spaces but found 1
47 | WARNING | Equals sign not aligned with surrounding assignments
51 | ERROR | Missing function doc comment
88 | ERROR | Line not indented correctly; expected 9 spaces but found 6
--------------------------------------------------------------------------------
<ENTER> to recheck, [s] to skip or [q] to quit :
PHP_CodeSniffer will always print the full error report for a file when running in interactive mode. Any report types you specify on the command line will be ignored.
Specifying a Report Width
By default, PHP_CodeSniffer will print all screen-based reports 80 characters wide. File paths will be truncated if they don't fit within this limit and error messages will be wrapped across multiple lines. You can increase the report width to show longer file paths and limit the wrapping of error messages using the -report-width command line argument.
Setting the report width to be 120 characters
$ phpcs --report-width=120 --report=summary /path/to/code/myfile.php
Writing a Report to a File
PHP_CodeSniffer always prints the specified report to the screen, but it can also be told to write a copy of the report to a file. When writing to a file, all internal parsing errors and verbose output PHP_CodeSniffer produces will not be included in the file. This feature is particularly useful when using report types such as XML and CSV that are often parsed by scripts or used with continuous integration software.
To write a copy of a report to a file, use the --report-file command line argument.
Writing a report to a file
$ phpcs --report=xml --report-file=/path/to/file.xml /path/to/code
The report will not be written to the screen when using this option. If you still want to view the report, use the -v command line argument to print verbose output.
Configuration Options
Configuration Options – A list of configuration options
PHP_CodeSniffer Configuration Options
Setting the Default Coding Standard
By default, PHP_CodeSniffer will use the PEAR coding standard if no standard is supplied on the command line. You can change the default standard by setting the default_standard configuration option.
Setting the default standard to be the Squiz coding standard
$ phpcs --config-set default_standard Squiz
Setting the Default Report Format
By default, PHP_CodeSniffer will use the full report format if no format is supplied on the command line. You can change the default report format by setting the report_format configuration option.
Setting the default report format to be the summary report
$ phpcs --config-set report_format summary
Hiding Warnings by Default
By default, PHP_CodeSniffer will show both errors and warnings for your code. You can hide warnings for a single script run by using the -n command line argument, but you can also enable this by default if you prefer. To hide warnings by default, set the show_warnings configuration option to 0.
Hiding warnings by default
$ phpcs --config-set show_warnings 0
When warnings are hidden by default, you can use the -w command line argument to show them for a single script run.
Showing Progress by Default
By default, PHP_CodeSniffer will run quietly and only print the report of errors and warnings at the end. If you want to know what is happening you can turn on progress output, but you can also enable this by default if you prefer. To show progress by default, set the show_progress configuration option to 1.
Showing progress by default
$ phpcs --config-set show_progress 1
Changing the Default Severity Levels
By default, PHP_CodeSniffer will show all errors and warnings with a severity level of 5 or greater. You can change these settings for a single script run by using the --severity, --error-severity and --warning-severity command line arguments, but you can also change the default settings if you prefer.
Changing the default severity level to show all errors and warnings
$ phpcs --config-set severity 1
Changing the default severity levels to show all errors but only some warnings
$ phpcs --config-set error_severity 1
$ phpcs --config-set warning_severity 8
Setting the severity of warnings to0is the same as using the-ncommand line argument. If you set the severity of errors to0PHP_CodeSniffer will not show any errors, which may be useful if you just want to show the warnings.
Setting the Default Report Width
By default, PHP_CodeSniffer will print all screen-based reports 80 characters wide. File paths will be truncated if they don't fit within this limit and error messages will be wrapped across multiple lines. You can increase the report width to show longer file paths and limit the wrapping of error messages using the -report-width command line argument, but you can also change the default report width by setting the report_width configuration option.
Setting the default report width to be 120 characters
$ phpcs --config-set report_width 120
Setting the Default Encoding
By default, PHP_CodeSniffer will treat all source files as if they use ISO-8859-1 encoding. This can cause double-encoding problems when generating UTF-8 encoded XML reports. To help PHP_CodeSniffer encode reports correctly, you can specify the encoding of your source files using the --encoding command line argument, but you can also change the default encoding by setting the encoding configuration option.
Setting the default encoding to UTF-8
$ phpcs --config-set encoding utf-8
Setting the Default Tab Width
By default, PHP_CodeSniffer will not convert tabs to spaces in checked files. Specifying a tab width will make PHP_CodeSniffer replace tabs with spaces. You can force PHP_CodeSniffer to replace tabs with spaces by default by setting the tab_width configuration option.
Setting the default tab width to be 4 spaces
$ phpcs --config-set tab_width 4
When the tab width is set by default, the replacement of tabs with spaces can be disabled for a single script run by setting the tab width to zero.Disabling the replacement of tabs with spaces
$ phpcs --tab-width=0 /path/to/code
Squiz Coding Standard Configuration Options
Setting the Path to JSLint
The Squiz coding standard includes a sniff that will check each JavaScript file using JSLint, a JavaScript program that looks for problems in JavaScript programs. Use the jslint_path configuration option to tell the JSLint sniff where to find the tool.
Setting the path to JSLint
$ phpcs --config-set jslint_path /path/to/jslint.js
As JSLint is just JavaScript code, you also need to install Rhino to be able to execute it. Use the rhino_path configuration option to tell the JSLint sniff where to find the tool.
Setting the path to Rhino
$ phpcs --config-set rhino_path /path/to/rhino
Setting the Path to JavaScript Lint
The Squiz coding standard includes a sniff that will check each JavaScript file using JavaScript Lint, a tool that checks all your JavaScript source code for common mistakes without actually running the script or opening the web page. Use the jsl_path configuration option to tell the JavaScript Lint sniff where to find the tool.
Setting the path to JavaScript Lint
$ phpcs --config-set jsl_path /path/to/jsl
Setting the Path to the Google Closure Linter
The Squiz coding standard includes a sniff that will check each file using the Google Closure Linter, an open source JavaScript style checker from Google. Use the gjslint_path configuration option to tell the Google Closure Linter sniff where to find the tool.
Setting the path to the Google Closure Linter
$ phpcs --config-set gjslint_path /path/to/gjslint
Zend Coding Standard Configuration Options
Setting the Path to the Zend Code Analyzer
The Zend coding standard includes a sniff that will check each file using the Zend Code Analyzer, a tool that comes with Zend Studio. Use the zend_ca_path configuration option to tell the Zend Code Analyzer sniff where to find the tool.
Setting the path to the Zend Code Analyzer
$ phpcs --config-set zend_ca_path /path/to/ZendCodeAnalyzer
Coding Standard Tutorial
Coding Standard Tutorial – A guide to writing your own code sniffs
Introduction
In this tutorial, we will create a new coding standard with a single sniff. Our sniff will prohibit the use of Perl style hash comments.
Creating the Coding Standard Directory
All sniffs in PHP_CodeSniffer must belong to a coding standard. A coding standard is a directory with a specific sub-directory structure and a ruleset.xml file, so we can create one very easily. Let's call our coding standard MyStandard. Run the following commands to create the coding standard directory structure:
$ mkdir MyStandard
$ mkdir MyStandard/Sniffs
As this coding standard directory sits outside the main PHP_CodeSniffer directory structure, PHP_CodeSniffer will not show it as an installed standard when using the-icommand line argument. If you want your standard to be shown as installed, create the MyStandard directory inside the PHP_CodeSniffer install:
$ cd /path/to/PHP_CodeSniffer/CodeSniffer/Standards
$ mkdir MyStandard
$ mkdir MyStandard/Sniffs
The MyStandard directory represents our coding standard. The Sniffs sub-directory is used to store all the sniff files for this coding standard.
Now that our directory structure is created, we need to add our ruleset.xml file. This file will allow PHP_CodeSniffer to ask our coding standard for information about itself, and also identify this directory as one that contains code sniffs.
$ cd MyStandard
$ touch ruleset.xml
The content of the ruleset.xml file should be the following:
<?xml version="1.0"?>
<ruleset name="MyStandard">
<description>A custom coding standard.</description>
</ruleset>
The ruleset.xml can be left quite small, as it is in this example coding standard. For information about the other features that the ruleset.xml provides, see the annotated ruleset.xml.
Creating the Sniff
A sniff requires a single PHP file. It's name should clearly describe the standard that we are enforcing and must end with Sniff.php. For our sniff, we will name the PHP file DisallowHashCommentsSniff.php and place it into a Commenting sub-directory to categorise this sniff as relating to commenting. Run the following commands to create the category and the sniff:
$ cd Sniffs
$ mkdir Commenting
$ touch Commenting/DisallowHashCommentsSniff.php
It does not matter what sub-directories you use for categorising your sniffs. Just make them descriptive enough so you can find your sniffs again later when you want to modify them.
Each sniff must implement the PHP_CodeSniffer_Sniff interface so that PHP_CodeSniffer knows that it should instantiate the sniff once it's invoked. The PHP_CodeSniffer_Sniff interface defines two methods that must be implemented; register() and process().
The register() and process() Methods
The register() method allows a sniff to subscribe to one or more token types that it wants to process. Once PHP_CodeSniffer encounters one of those tokens, it calls the process() method with the PHP_CodeSniffer_File object (a representation of the current file being checked) and the position in the stack where the token was found.
For our sniff, we are interested in single line comments. The token_get_all() method that PHP_CodeSniffer uses to acquire the tokens within a file distinguishes doc comments and normal comments as two separate token types. Therefore, we don't have to worry about doc comments interfering with our test. The register() method only needs to return one token type, T_COMMENT.
The Token Stack
A sniff can gather more information about a token by acquiring the token stack with a call to the getTokens() method on the PHP_CodeSniffer_File object. This method returns an array and is indexed by the position where the token occurs in the token stack. Each element in the array represents a token. All tokens have a code, type and a content index in their array. The code value is a unique integer for the type of token. The type value is a string representation of the token (e.g., 'T_COMMENT' for comment tokens). The type has a corresponding globally defined integer with the same name. Finally, the content value contains the content of the token as it appears in the code.
Some tokens have more indexes than those described above. Have a look in the PHP/CodeSniffer/File.php class comment for a full list of token indexes.
Reporting Errors
Once an error is detected, a sniff should indicate that an error has occurred by calling the addError() method on the PHP_CodeSniffer_File object, passing in an appropriate error message as the first argument, the position in the stack where the error was detected as the second, a code to uniquely identify the error within this sniff and an array of data used inside the error message. Alternatively, if the violation is considered not as critical as an error, the addWarning() method can be used.
DisallowHashCommentsSniff.php
We now have to write the content of our sniff. The content of the DisallowHashCommentsSniff.php file should be the following:
<?php
/**
* This sniff prohibits the use of Perl style hash comments.
*
* PHP version 5
*
* @category PHP
* @package PHP_CodeSniffer
* @author Your Name <you@domain.net>
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
* @version SVN: $Id: coding-standard-tutorial.xml,v 1.9 2008-10-09 15:16:47 cweiske Exp $
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
/**
* This sniff prohibits the use of Perl style hash comments.
*
* An example of a hash comment is:
*
* <code>
* # This is a hash comment, which is prohibited.
* $hello = 'hello';
* </code>
*
* @category PHP
* @package PHP_CodeSniffer
* @author Your Name <you@domain.net>
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
* @version Release: @package_version@
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
class MyStandard_Sniffs_Commenting_DisallowHashCommentsSniff implements PHP_CodeSniffer_Sniff
{
/**
* Returns the token types that this sniff is interested in.
*
* @return array(int)
*/
public function register()
{
return array(T_COMMENT);
}//end register()
/**
* Processes the tokens that this sniff is interested in.
*
* @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
* @param int $stackPtr The position in the stack where
* the token was found.
*
* @return void
*/
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
if ($tokens[$stackPtr]['content']{0} === '#') {
$error = 'Hash comments are prohibited; found %s';
$data = array(trim($tokens[$stackPtr]['content']));
$phpcsFile->addError($error, $stackPtr, 'Found', $data);
}
}//end process()
}//end class
?>
By default, PHP_CodeSniffer assumes all sniffs are designed to check PHP code only. You can specify a list of tokenizers that your sniff supports, allowing it to be used wth PHP, JavaScript or XML files, or any combination of the three. You do this by setting the$supportedTokenizersmember variable in your sniff. Adding the following code to your sniff will tell PHP_CodeSniffer that it can be used to check both PHP and JavaScript code:<?php /** * A list of tokenizers this sniff supports. * * @var array */ public $supportedTokenizers = array( 'PHP', 'JS', ); ?>
Results
Now that we have defined a coding standard, let's validate a file that contains hash comments.
The test file we are using has the following contents:
<?php
# Check for valid contents.
if ($obj->contentsAreValid($array)) {
$value = $obj->getValue();
# Value needs to be an array.
if (is_array($value) === false) {
# Error.
$obj->throwError();
exit();
}
}
?>
When PHP_CodeSniffer is run on the file using our new coding standard, 3 errors will be reported:
$ phpcs --standard=/path/to/MyStandard test.php
FILE: test.php
--------------------------------------------------------------------------------
FOUND 3 ERROR(S) AFFECTING 3 LINE(S)
--------------------------------------------------------------------------------
3 | ERROR | Hash comments are prohibited; found # Check for valid contents.
7 | ERROR | Hash comments are prohibited; found # Value needs to be an array.
9 | ERROR | Hash comments are prohibited; found # Error.
--------------------------------------------------------------------------------
Note that we pass the absolute path to our coding standard directory on the command line because our standard is not installed inside the main PHP_CodeSniffer directory structure. If you have created your standard inside PHP_CodeSniffer, you can simply pass the name of the standard:
$ phpcs --standard=MyStandard Test.php
Annotated ruleset.xml
Annotated ruleset.xml – A sample ruleset.xml file that describes all features of the format
Introduction
PHP_CodeSniffer allows developers to design their own coding standards by creating a simple ruleset XML file that both pulls in sniffs from existing standards and customises them for the developer's needs. This XML file can be named anything you like, as long as it has an xml extension and complies to the ruleset.xml format. The file can be stored anywhere, making it perfect for placing under version control with a project's source code and unit tests.
Once created, a ruleset file can be used with the --standard command line argument. In the following example, PHP_CodeSniffer will use the coding standard defined in a custom ruleset file called custom_ruleset.xml:
Using a custom ruleset file
$ phpcs --standard=/path/to/custom_ruleset.xml test.php
The Annotated Sample File
The following sample file documents the ruleset.xml format and shows you the complete range of features that the format supports. The file is designed for documentation purposes only and is not a working coding standard.
<?xml version="1.0"?>
<ruleset name="Custom Standard">
<!--
The name attribute of the ruleset tag is displayed
when running PHP_CodeSniffer with the -v command line
argument. The description tag below is not displayed anywhere
except in this file, so it can contain information for
developers who may change this file in the future.
-->
<description>A custom coding standard</description>
<!--
You can hard-code ignore patterns directly into your
custom standard so you don't have to specify the
patterns on the command line.
The following two tags are equivalent to the command line
argument: --ignore=*/tests/*,*/data/*
-->
<exclude-pattern>*/tests/*</exclude-pattern>
<exclude-pattern>*/data/*</exclude-pattern>
<!--
Include all sniffs in the PEAR standard. Note that the
path to the standard does not have to be specified as the
PEAR standard exists inside the PHP_CodeSniffer install
directory.
-->
<rule ref="PEAR"/>
<!--
Include all sniffs in an external standard directory. Note
that we have to specify the full path to the standard's
directory because it does not exist inside the PHP_CodeSniffer
install directory.
-->
<rule ref="/home/username/standards/mystandard"/>
<!--
Include everything in another ruleset.xml file. This is
really handy if you want to customise another developer's
custom standard. They just need to distribute their single
ruleset file to allow this.
-->
<rule ref="/home/username/standards/custom.xml"/>
<!--
Include all sniffs in the Squiz standard except one. Note that
the name of the sniff being excluded is the code that the sniff
is given by PHP_CodeSniffer and is based on the file name and
path of the sniff class. You can display these codes using the
-s command line argument when checking a file.
-->
<rule ref="Squiz">
<exclude name="Squiz.PHP.CommentedOutCode"/>
</rule>
<!--
Include some specific sniffs from the Generic standard.
Note again that the name of the sniff is the code that
PHP_CodeSniffer gives it.
-->
<rule ref="Generic.CodeAnalysis.UnusedFunctionParameter"/>
<rule ref="Generic.Commenting.Todo"/>
<rule ref="Generic.ControlStructures.InlineControlStructure"/>
<!--
Here we are including a specific sniff but also changing
the error message of a specific message inside the sniff.
Note that the specific code for the message, which is
CommentFound in this case, is defined by the sniff developer.
You can display these codes by using the -s command line
argument when checking a file.
Also note that this message has a variable inside it,
which is why it is important that sniffs use a printf style
format for their error messages.
We also drop the severity of this message from the
default value (5) so that it is hidden by default. It can be
displayed by setting the minimum severity on the PHP_CodeSniffer
command line. This is great if you want to use some messages
only in code reviews and not have them block code commits.
-->
<rule ref="Generic.Commenting.Todo.CommentFound">
<message>Please review this TODO comment: %s</message>
<severity>3</severity>
</rule>
<!--
Here we change two messages from the same sniff. Note how the
codes are slightly different because the sniff developer has
defined both a MaxExceeded message and a TooLong message. In the
case of this sniff, one is used for warnings and one is used
for errors.
-->
<rule ref="Generic.Files.LineLength.MaxExceeded">
<message>Line contains %s chars, which is longer than the max limit of %s</message>
</rule>
<rule ref="Generic.Files.LineLength.TooLong">
<message>Line longer than %s characters; contains %s characters</message>
</rule>
<!--
Some sniffs have public member vars that allow you to
customise specific elements of the sniff. In the case of
the Generic LineLength sniff, you can customise the limit
at which the sniff will throw warnings and the limit at
which it will throw errors.
The rule below includes the LineLength sniff but changes the
settings so the sniff will show warnings for any line longer
than 90 chars and errors for any line longer than 100 chars.
-->
<rule ref="Generic.Files.LineLength">
<properties>
<property name="lineLimit" value="90"/>
<property name="absoluteLineLimit" value="100"/>
</properties>
</rule>
<!--
Another useful example of changing sniff settings is
to specify the end of line character that your standard
should check for.
-->
<rule ref="Generic.Files.LineEndings">
<properties>
<property name="eolChar" value="\r\n"/>
</properties>
</rule>
<!--
Boolean values should be specified by using the strings
"true" and "false" rather than the integers 0 and 1.
-->
<rule ref="Generic.Formatting.MultipleStatementAlignment">
<properties>
<property name="maxPadding" value="8"/>
<property name="ignoreMultiLine" value="true"/>
<property name="error" value="true"/>
</properties>
</rule>
<!--
If you want to completely disable an error message in a sniff
but you don't want to exclude the whole sniff, you can
change the severity of the message to 0. In this case, we
want the Squiz DoubleQuoteUsage sniff to be included in our
standard, but we don't want the ContainsVar error message to
ever be displayed.
-->
<rule ref="Squiz.Strings.DoubleQuoteUsage.ContainsVar">
<severity>0</severity>
</rule>
<!--
There is a special internal error message produced by PHP_CodeSniffer
when it is unable to detect code in a file, possible due to
the use of short open tags even though php.ini disables them.
You can disable this message in the same way as sniff messages.
Again, the code here will be displayed in the PHP_CodeSniffer
output when using the -s command line argument while checking a file.
-->
<rule ref="Internal.NoCodeFound">
<severity>0</severity>
</rule>
<!--
You can also hard-code ignore patterns for specific sniffs,
a feature not available on the command line.
The code here will hide all messages from the Squiz DoubleQuoteUsage
sniff for files that match either of the two exclude patterns.
-->
<rule ref="Squiz.Strings.DoubleQuoteUsage">
<exclude-pattern>*/tests/*</exclude-pattern>
<exclude-pattern>*/data/*</exclude-pattern>
</rule>
<!--
You can also be more specific and just exclude some messages.
The code here will just hide the ContainsVar error generated by the
Squiz DoubleQuoteUsage sniff for files that match either of the two
exclude patterns.
-->
<rule ref="Squiz.Strings.DoubleQuoteUsage.ContainsVar">
<exclude-pattern>*/tests/*</exclude-pattern>
<exclude-pattern>*/data/*</exclude-pattern>
</rule>
</ruleset>
Using the Subversion pre-commit Hook
Using the Subversion pre-commit Hook – How to configure the Subversion pre-commit hook
What Does the Subversion pre-commit Hook Do?
The SVN pre-commit hook has different requirements than the main PHP_CodeSniffer package. See the Requirements page for more information.
A pre-commit hook is a feature available in the Subversion version control system that allows code to be validated before it is committed to the repository. The PHP_CodeSniffer pre-commit hook allows you to check code for coding standard errors and stop the commit process if errors are found. This ensures developers are not able to commit code that violates your coding standard. Instead, they are presented with the list of errors they need to correct before committing.
Sample pre-commit output
$ svn commit -m "Test" temp.php
Sending temp.php
Transmitting file data .svn: Commit failed (details follow):
svn: 'pre-commit' hook failed with error output:
FILE: temp.php
---------------------------------------------------------------
FOUND 1 ERROR(S) AND 0 WARNING(S) AFFECTING 1 LINE(S)
---------------------------------------------------------------
2 | ERROR | Missing file doc comment
--------------------------------------------------------------
Configuring the pre-commit Hook
Edit /path/to/PHP_CodeSniffer/scripts/phpcs-svn-pre-commit and replace @php_bin@ in the first line with the path to the PHP CLI. For example, #!@php_bin@ becomes #!/usr/bin/php.
Now ensure the path to svnlook is correct by modifying the following line, if required:
Changing the path to svnlook
define('PHP_CODESNIFFER_SVNLOOK', '/usr/bin/svnlook');
Now add the following line to your pre-commit file in the Subversion hooks directory:
Adding the pre-commit hook to the Subversion config file
/path/to/PHP_CodeSniffer/scripts/phpcs-svn-pre-commit "$REPOS" -t "$TXN" >&2 || exit 1
You can also use all the standard phpcs command line options to do things like set the standard to use, the tab width and the error report format:
Adding the pre-commit hook to the Subversion config file
/path/to/PHP_CodeSniffer/scripts/phpcs-svn-pre-commit --standard=Squiz --tab-width=4 "$REPOS" -t "$TXN" >&2 || exit 1
FAQ
FAQ – Frequently asked questions
Does PHP_CodeSniffer perform any code coverage or unit testing?
No. PHP_CodeSniffer is not a tool for testing that your PHP application works correctly. All PHP_CodeSniffer will do is ensure your PHP code meets the standards that you are following.
My code is fine! Why do I need PHP_CodeSniffer?
Maybe you don't, but if you want to ensure you adhere to a set of coding standards, PHP_CodeSniffer is a quick and easy way to do that. PHP_CodeSniffer is a replacement for the more manual task of checking coding standards in code reviews. With PHP_CodeSniffer, you can reserve code reviews for the checking of code correctness.
Coding standards are a good thing. They will make your code easier to read and maintain, especially when multiple developers are working on the same application. Consider using coding standards if you don't already.
Does PHP_CodeSniffer parse my code to ensure it will execute?
No. PHP_CodeSniffer does not actually parse your code, and so cannot accurately tell if your code contains parse errors. PHP_CodeSniffer does know about some parse errors and will warn you if it finds code that it is unable to sniff correctly due to a suspected parse error. However, as there is no actual parsing taking place, PHP_CodeSniffer may return an incorrect number of errors when checking code that does contain parse errors.
You can easily check for parse errors in a file using the PHP command line interface and the
-l(lowercase L) option.
$ php -l /path/to/code/myfile.inc
No syntax errors detected in /path/to/code/myfile.inc
I don't agree with your coding standards! Can I make PHP_CodeSniffer enforce my own?
Yes. At its core, PHP_CodeSniffer is just a framework for enforcing coding standards. We release PHP_CodeSniffer with some sample coding standards to help developers get started on projects where there is no standard defined. If you want to write your own standard, read the tutorial on creating coding standards.
How come PHP_CodeSniffer reported errors, I fixed them, now I get even more?
Sometimes, errors mask the existence of other errors, or new errors are created as you fix others. For example, PHP_CodeSniffer might tell you that an inline IF statement needs to be defined with braces. Once you make this change, PHP_CodeSniffer may report that the braces you added are not correctly aligned.
Always run PHP_CodeSniffer until you get a passing result. Once you've made the changes PHP_CodeSniffer recommends, run PHP_CodeSniffer again to ensure no new errors have been added.
Why doesn't PHP_CodeSniffer just make the changes it suggests for me?
As much as we trust PHP_CodeSniffer to check your code for coding standard errors, we don't trust any application to ever change code for us without reviewing it first. Considering you would have to check each change PHP_CodeSniffer made before releasing the source code, why not make the changes manually?
Making the changes manually ensures a couple of positive things happen:
- Developers learn the coding standards and make less mistakes in the future.
- Developers can ensure that PHP_CodeSniffer is working correctly.
- Developers can decide if a coding standard doesn't fit a particular piece of code.
So if you find yourself wishing PHP_CodeSniffer would just go ahead and make those changes for you, maybe you just need to read the coding standards and adhere to them a bit better.
No matter how small of a change you make, always test your code before committing it to your code repository or releasing it. Even changes suggested by PHP_CodeSniffer need to be tested, as small and insignificant as they may seem.
What does PHP_CodeSniffer use to tokenize my code?
For PHP files, PHP_CodeSniffer uses PHP's inbuilt tokenizer functions to parse your code. It then changes that output to include much more data about the file, such as matching function braces to function keywords.
For all other file types, PHP_CodeSniffer includes a custom tokenizer that either makes use of PHP's inbuilt tokenizer or emulates it. In both cases, the token array must be checked and changed manually before all the standard PHP_CodeSniffer matching rules are applied, making tokenizing a bit slower for these file types.