Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP_CodeSniffer rules documentation [closed]

Tags:

Where is it possible to find documentation on PHP_CodeSniffer rules available? Seems to me like the rules exist, but nobody knows the list of them and their properties. I faced the essential problem, I want to customize a standard and force curly brace start on the same line after statement divided by one space and cannot see any way to do it. And this is only one issue, but I have many others. Thank you.

like image 414
Alexander Avatar asked May 07 '13 19:05

Alexander


People also ask

How to ignore phpcs?

With the following comments you can ignore whatever part of a file you would like. With // phpcs:ignore and // phpcs:disable you can also specify which messages, sniffs, categories or standards you would like to disable, for example: // phpcs:ignore Squiz.

What is code sniffer?

Code Sniffer is a static test that uses static code analysis to detect violations of the Magento Coding Standard to prevent common coding errors.

How do I use Phpcs?

In the Settings dialog, go to Editor > Inspections. From the inspections screen, expand the PHP | Quality tools node and enable “PHP CodeSniffer validation”. In the configuration pane that is now enabled, select “Custom” from the “Coding standard” dropdown, locate the ruleset configuration ( phpcs.

How to install code sniffer in PhpStorm?

In the Settings/Preferences dialog ( Ctrl+Alt+S ), navigate to PHP | Quality Tools. next to the Configuration list. In the PHP_CodeSniffer dialog that opens, empty the PHP_CodeSniffer path field. Update the project Composer dependencies by clicking Update on top of the composer.


2 Answers

Looking at the source code can be frightening, but in the end, if you want to list all possible rules (or sniffs as PHP_CodeSniffer calls them) you have to look at the source code.

I had the same problem, and I used three techniques:

1. Option -s

phpcs command has an option that outputs the identifier of not followed sniffs. Let's look at an example:

$ phpcs -p -s --extensions=php /path/to/my/source/code  ...E...E....W.....W..E.............W........................  60 / 723 (8%) .......................W.................................... 120 / 723 (17%) .............................W..W....E..................E..E 180 / 723 (25%)  ----------------------------------------------------------------------  60 | ERROR   | [x] Line indented incorrectly; expected at least 2 spaces,     |         |     found 0 (Generic.WhiteSpace.ScopeIndent.Incorrect) ----------------------------------------------------------------------  61 | WARNING | Comment refers to a TODO task "Improve readability"     |         | (Generic.Commenting.Todo.TaskFound) ----------------------------------------------------------------------  ... output has been truncated Time: 2 mins, 9.46 secs; Memory: 25.5Mb 

In the report, each error or warning outputs the sniff.

2. ruleset.xml files in the source code

The configuration of which rules must be followed or ignored in a project are usually defined in a ruleset.xml file. The PHP_CodeSniffer source code has some examples of them. PHP_CodeSniffer defines several standards: Generic, PSR1, PSR2,... Each of them has a ruleset.xml file. You can learn from them how to create your own.

This technique requires you to look at the source code, but you just need to read files similar to what you probably have in your project. For example, you can find the ruleset.xml file for PSR2 standard under the CodeSniffer/Standards/PSR2 folder.

3. Eventually, the source code

In the end, if you want the comprehensive list of sniffs, you need to extract them from the source code. Let's decode how sniff identifiers are built.

It's easy to know the PHP class that implements a sniff. For example, let's take Generic.Commenting.Todo.TaskFound. The three first tokens mean:

  1. Generic: it is the standard, and it defines the standard's folder CodeSniffer/Standards/Generic
  2. Commenting: it is the sniff group under the standard, and it also points to a folder inside the standard: CodeSniffer/Standards/Generic/Sniffs/Commenting
  3. Todo: it is the sniff, and it is implemented in a class called <sniff name>Sniff.php

So, we have that Generic.Commenting.Todo.TaskFound sniff is implemented in the CodeSniffer/Standards/Generic/Sniffs/Commenting/TodoSniff.php class.

We can do the other way around. If we know the path to a PHP class, we are able to know the sniff PHP_CodeSniffer is going to report. For example, the class implemented in CodeSniffer/Standards/Squiz/Sniffs/NamingConventions/ValidFunctionNameSniff.php will generate sniffs with the identifier Squiz.NamingConventions.ValidFunctionName.

like image 165
rchavarria Avatar answered Oct 05 '22 04:10

rchavarria


Try this PHP script.

Change $standardsDirectory to proper path.

<?php   /**  * PHP_CodeSniffer "Standards" directory!  */ $standardsDirectory = __DIR__. '/Standards';   /**  * Scan directory (recursive)  */ function _scandir($path) {     $list = [];      $elms = scandir($path);     if(!$elms)         return false;      foreach($elms as $elm)     {         if($elm == '.' || $elm == '..')             continue;          $fullpath = $path .'/'. $elm;          if(is_file($fullpath))         {             $list[] = $fullpath;         }         elseif(is_dir($fullpath))         {             $sublist = _scandir($fullpath);             $list = array_merge($list, $sublist);         }     }      return $list; }    $list = [];  $files = _scandir($standardsDirectory); foreach($files as $file) {     if(preg_match('@Standards/(.*?)/Sniffs/(.*?)/(.*?)Sniff.php@i', $file, $matches))     {         $key = $matches[2] .'.'. $matches[3];          $desc = null;         $data = file_get_contents($file);         if($data)         {             $data = explode("\n", $data);             $desc = trim($data[2], " \t*");         }          $list[ $key ] = [             'shortName'     => $matches[2] .'.'. $matches[3],             'fullName'      => $matches[1] .'.'. $matches[2] .'.'. $matches[3],             'path'          => $matches[0],             'desc'          => $desc,         ];     } }  ksort($list);  ?> <html> <body style="font-family: Consolas, 'Lucida Console';">      <table>     <?php foreach($list as $e): ?>     <tr align="left">         <th><?=$e['shortName']?></th>         <td><?=$e['fullName']?></td>         <td><?=$e['desc']?></td>     </tr>     <?php endforeach; ?>     </table>  </body> </html> 
like image 28
l00k Avatar answered Oct 05 '22 05:10

l00k