Skip to content

Commit ae14dab

Browse files
committed
Coding-Standard-Tutorial: update the tutorial
* Remove mention of creating the standards in the PHPCS `Standards` directory and replace it with information about registering a standard with PHPCS via the `installed_paths` command. * Add note about the token array containing additional information. * Modernize the sniff code sample. - Replace the file docblock with a simpler class docblock. - Use the correct namespace for the standard. - Make it a `final` class. - Use short arrays. - Remove `//end ...` comments. - Improve type specificity in the docblocks. - Remove PHP close tag. * Improve the test code by including code samples which should *not* be flagged (but would trigger the sniff). * Use the more common term (class) "property" instead of "member variable". * Fix grammatical error. * Use fenced code blocks for bash commands. * Various other markdown tweaks for readability.
1 parent 18cf646 commit ae14dab

File tree

1 file changed

+60
-66
lines changed

1 file changed

+60
-66
lines changed

wiki/Coding-Standard-Tutorial.md

Lines changed: 60 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,29 @@ In this tutorial, we will create a new coding standard with a single sniff. Our
22

33
## Creating the Coding Standard Directory
44

5-
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:
5+
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:
66

7-
$ mkdir MyStandard
8-
$ mkdir MyStandard/Sniffs
7+
```bash
8+
$ mkdir MyStandard
9+
$ mkdir MyStandard/Sniffs
10+
```
911

10-
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 `-i` command line argument. If you want your standard to be shown as installed, create the MyStandard directory inside the PHP_CodeSniffer install:
12+
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 `-i` command line argument. If you want your standard to be shown as installed, [register the MyStandard directory as an external standards with PHP_CodeSniffer](https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki/Configuration-Options#setting-the-installed-standard-paths):
1113

12-
$ cd /path/to/PHP_CodeSniffer/src/Standards
13-
$ mkdir MyStandard
14-
$ mkdir MyStandard/Sniffs
14+
```bash
15+
$ phpcs --config-set installed_paths /path/to/MyStandard
16+
```
1517

1618
The `MyStandard` directory represents our coding standard. The `Sniffs` sub-directory is used to store all the sniff files for this coding standard.
1719

18-
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.
20+
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.
1921

20-
$ cd MyStandard
21-
$ touch ruleset.xml
22+
```bash
23+
$ cd MyStandard
24+
$ touch ruleset.xml
25+
```
2226

23-
The content of the `ruleset.xml` file should be the following:
27+
The content of the `ruleset.xml` file should, at a minimum, be the following:
2428

2529
```xml
2630
<?xml version="1.0"?>
@@ -30,15 +34,17 @@ The content of the `ruleset.xml` file should be the following:
3034
```
3135

3236
> [!NOTE]
33-
> 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]].
37+
> 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]].
3438
3539
## Creating the Sniff
3640

37-
A sniff requires a single PHP file that must be placed into a sub-directory to categorise the type of check it performs. 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:
41+
A sniff requires a single PHP file that must be placed into a sub-directory to categorise the type of check it performs. Its 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:
3842

39-
$ cd Sniffs
40-
$ mkdir Commenting
41-
$ touch Commenting/DisallowHashCommentsSniff.php
43+
```bash
44+
$ cd Sniffs
45+
$ mkdir Commenting
46+
$ touch Commenting/DisallowHashCommentsSniff.php
47+
```
4248

4349
> [!NOTE]
4450
> 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.
@@ -53,49 +59,43 @@ For our sniff, we are interested in single line comments. The `token_get_all` me
5359

5460
## The Token Stack
5561

56-
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\Files\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.
62+
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\Files\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.
63+
64+
> [!NOTE]
65+
> Depending on the token, the token array may contain various additional indexes with further information on a token.
5766
5867
## Reporting Errors
5968

60-
Once an error is detected, a sniff should indicate that an error has occurred by calling the `addError` method on the `PHP_CodeSniffer\Files\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.
69+
Once an error is detected, a sniff should indicate that an error has occurred by calling the `addError` method on the `PHP_CodeSniffer\Files\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.
70+
Alternatively, if the violation is considered not as critical as an error, the `addWarning` method can be used.
6171

6272
## DisallowHashCommentsSniff.php
6373

6474
We now have to write the content of our sniff. The content of the `DisallowHashCommentsSniff.php` file should be the following:
6575

6676
```php
6777
<?php
68-
/**
69-
* This sniff prohibits the use of Perl style hash comments.
70-
*
71-
* PHP version 5
72-
*
73-
* @category PHP
74-
* @package PHP_CodeSniffer
75-
* @author Your Name <you@domain.net>
76-
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
77-
*/
7878

79-
namespace PHP_CodeSniffer\Standards\MyStandard\Sniffs\Commenting;
79+
namespace MyStandard\Sniffs\Commenting;
8080

8181
use PHP_CodeSniffer\Sniffs\Sniff;
8282
use PHP_CodeSniffer\Files\File;
8383

84-
class DisallowHashCommentsSniff implements Sniff
84+
/**
85+
* This sniff prohibits the use of Perl style hash comments.
86+
*/
87+
final class DisallowHashCommentsSniff implements Sniff
8588
{
8689

87-
8890
/**
8991
* Returns the token types that this sniff is interested in.
9092
*
91-
* @return array(int)
93+
* @return array<int|string>
9294
*/
9395
public function register()
9496
{
95-
return array(T_COMMENT);
96-
97-
}//end register()
98-
97+
return [T_COMMENT];
98+
}
9999

100100
/**
101101
* Processes this sniff, when one of its tokens is encountered.
@@ -111,30 +111,25 @@ class DisallowHashCommentsSniff implements Sniff
111111
$tokens = $phpcsFile->getTokens();
112112
if ($tokens[$stackPtr]['content'][0] === '#') {
113113
$error = 'Hash comments are prohibited; found %s';
114-
$data = array(trim($tokens[$stackPtr]['content']));
114+
$data = [trim($tokens[$stackPtr]['content'])];
115115
$phpcsFile->addError($error, $stackPtr, 'Found', $data);
116116
}
117-
118-
}//end process()
119-
120-
121-
}//end class
122-
123-
?>
117+
}
118+
}
124119
```
125120

126-
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 CSS files, or any combination of the three. You do this by setting the `$supportedTokenizers` member 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:
121+
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 CSS files, or any combination of the three. You do this by setting the `$supportedTokenizers` property 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:
127122

128123
```php
129124
/**
130125
* A list of tokenizers this sniff supports.
131126
*
132-
* @var array
127+
* @var array<string>
133128
*/
134-
public $supportedTokenizers = array(
129+
public $supportedTokenizers = [
135130
'PHP',
136131
'JS',
137-
);
132+
];
138133
```
139134

140135

@@ -145,7 +140,11 @@ Now that we have defined a coding standard, let's validate a file that contains
145140
```php
146141
<?php
147142

148-
# Check for valid contents.
143+
// Slash comments should be ignored.
144+
145+
/* Star comments should also be ignored. */
146+
147+
# Hash comments should be flagged.
149148
if ($obj->contentsAreValid($array)) {
150149
$value = $obj->getValue();
151150

@@ -156,23 +155,18 @@ if ($obj->contentsAreValid($array)) {
156155
exit();
157156
}
158157
}
159-
160-
?>
161158
```
162159

163160
When PHP_CodeSniffer is run on the file using our new coding standard, 3 errors will be reported:
164-
165-
$ phpcs --standard=/path/to/MyStandard test.php
166-
167-
FILE: test.php
168-
--------------------------------------------------------------------------------
169-
FOUND 3 ERROR(S) AFFECTING 3 LINE(S)
170-
--------------------------------------------------------------------------------
171-
3 | ERROR | Hash comments are prohibited; found # Check for valid contents.
172-
7 | ERROR | Hash comments are prohibited; found # Value needs to be an array.
173-
9 | ERROR | Hash comments are prohibited; found # Error.
174-
--------------------------------------------------------------------------------
175-
176-
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:
177-
178-
$ phpcs --standard=MyStandard Test.php
161+
```bash
162+
$ phpcs --standard=MyStandard test.php
163+
164+
FILE: test.php
165+
--------------------------------------------------------------------------------
166+
FOUND 3 ERROR(S) AFFECTING 3 LINE(S)
167+
--------------------------------------------------------------------------------
168+
7 | ERROR | Hash comments are prohibited; found # Hash comments should be flagged.
169+
11 | ERROR | Hash comments are prohibited; found # Value needs to be an array.
170+
13 | ERROR | Hash comments are prohibited; found # Error.
171+
--------------------------------------------------------------------------------
172+
```

0 commit comments

Comments
 (0)