PHPCS: WordPress

Personal documentation for the sniffs available in the PHP Code Sniffer coding standards to help build an own rulesets and search for error explanations.

Generic.Classes.DuplicateClassName | [ref]

Class and Interface names should be unique in a project. They should never be duplicated.

Valid: A unique class name. Invalid: A class duplicated (including across multiple files).
class Foo
{
}
class Foo
{
}

class Foo
{
}

Generic.Classes.OpeningBraceSameLine | [ref]

The opening brace of a class must be on the same line after the definition and must be the last thing on that line.

Valid: Opening brace on the same line. Invalid: Opening brace on the next line.
class Foo {
}
class Foo
{
}
Valid: Opening brace is the last thing on the line. Invalid: Opening brace not last thing on the line.
class Foo {
}
class Foo { // Start of class.
}

Generic.CodeAnalysis.AssignmentInCondition | [ref]

Variable assignments should not be made within conditions.

Valid: A variable comparison being executed within a condition. Invalid: A variable assignment being made within a condition.
if ($test === 'abc') {
    // Code.
}
if ($test = 'abc') {
    // Code.
}

Generic.CodeAnalysis.EmptyPHPStatement | [ref]

Empty PHP tags are not allowed.

Valid: There is at least one statement inside the PHP tag pair. Invalid: There is no statement inside the PHP tag pair.
<?php echo 'Hello World'; ?>
<?= 'Hello World'; ?>
<?php ; ?>
<?=  ?>
Valid: There is no superfluous semi-colon after a PHP statement. Invalid: There are one or more superfluous semi-colons after a PHP statement.
function_call();
if (true) {
    echo 'Hello World';
}
function_call();;;
if (true) {
    echo 'Hello World';
};

Generic.CodeAnalysis.EmptyStatement | [ref]

Control Structures must have at least one statement inside of the body.

Valid: There is a statement inside the control structure. Invalid: The control structure has no statements.
if ($test) {
    $var = 1;
}
if ($test) {
    // do nothing
}

Generic.CodeAnalysis.ForLoopShouldBeWhileLoop | [ref]

For loops that have only a second expression (the condition) should be converted to while loops.

Valid: A for loop is used with all three expressions. Invalid: A for loop is used without a first or third expression.
for ($i = 0; $i < 10; $i++) {
    echo "{$i}\n";
}
for (;$test;) {
    $test = doSomething();
}

Generic.CodeAnalysis.ForLoopWithTestFunctionCall | [ref]

For loops should not call functions inside the test for the loop when they can be computed beforehand.

Valid: A for loop that determines its end condition before the loop starts. Invalid: A for loop that unnecessarily computes the same value on every iteration.
$end = count($foo);
for ($i = 0; $i < $end; $i++) {
    echo $foo[$i]."\n";
}
for ($i = 0; $i < count($foo); $i++) {
    echo $foo[$i]."\n";
}

Generic.CodeAnalysis.JumbledIncrementer | [ref]

Incrementers in nested loops should use different variable names.

Valid: Two different variables being used to increment. Invalid: Inner incrementer is the same variable name as the outer one.
for ($i = 0; $i < 10; $i++) {
    for ($j = 0; $j < 10; $j++) {
    }
}
for ($i = 0; $i < 10; $i++) {
    for ($j = 0; $j < 10; $i++) {
    }
}

Generic.CodeAnalysis.RequireExplicitBooleanOperatorPrecedence | [ref]

Forbids mixing different binary boolean operators (&&, ||, and, or, xor) within a single expression without making precedence clear using parentheses.

Valid: Making precedence clear with parentheses. Invalid: Not using parentheses.
$one = false;
$two = false;
$three = true;

$result = ($one && $two) || $three;
$result2 = $one && ($two || $three);
$result3 = ($one && !$two) xor $three;
$result4 = $one && (!$two xor $three);

if (
    ($result && !$result3)
    || (!$result && $result3)
) {}
$one = false;
$two = false;
$three = true;

$result = $one && $two || $three;

$result3 = $one && !$two xor $three;


if (
    $result && !$result3
    || !$result && $result3
) {}

Generic.CodeAnalysis.UnconditionalIfStatement | [ref]

If statements that are always evaluated should not be used.

Valid: An if statement that only executes conditionally. Invalid: An if statement that is always performed.
if ($test) {
    $var = 1;
}
if (true) {
    $var = 1;
}
Valid: An if statement that only executes conditionally. Invalid: An if statement that is never performed.
if ($test) {
    $var = 1;
}
if (false) {
    $var = 1;
}

Generic.CodeAnalysis.UnnecessaryFinalModifier | [ref]

Methods should not be declared final inside of classes that are declared final.

Valid: A method in a final class is not marked final. Invalid: A method in a final class is also marked final.
final class Foo
{
    public function bar()
    {
    }
}
final class Foo
{
    public final function bar()
    {
    }
}

Generic.CodeAnalysis.UnusedFunctionParameter | [ref]

All parameters in a functions signature should be used within the function.

Valid: All the parameters are used. Invalid: One of the parameters is not being used.
function addThree($a, $b, $c)
{
    return $a + $b + $c;
}
function addThree($a, $b, $c)
{
    return $a + $b;
}

Generic.CodeAnalysis.UselessOverridingMethod | [ref]

Methods should not be defined that only call the parent method.

Valid: A method that extends functionality on a parent method. Invalid: An overriding method that only calls the parent.
final class Foo
{
    public function bar()
    {
        parent::bar();
        $this->doSomethingElse();
    }
}
final class Foo
{
    public function bar()
    {
        parent::bar();
    }
}

Generic.Commenting.DocComment | [ref]


Generic.ControlStructures.InlineControlStructure | [ref]

Control Structures should use braces.

Valid: Braces are used around the control structure. Invalid: No braces are used for the control structure..
if ($test) {
    $var = 1;
}
if ($test)
    $var = 1;

Generic.Files.ByteOrderMark | [ref]

Byte Order Marks that may corrupt your application should not be used. These include 0xefbbbf (UTF-8), 0xfeff (UTF-16 BE) and 0xfffe (UTF-16 LE).


Generic.Files.LineEndings | [ref]

Unix-style line endings are preferred ("\n" instead of "\r\n").


Generic.Files.OneObjectStructurePerFile | [ref]

There should only be one class or interface or trait defined in a file.

Valid: Only one object structure in the file. Invalid: Multiple object structures defined in one file.
<?php
trait Foo
{
}
<?php
trait Foo
{
}

class Bar
{
}

Generic.Formatting.DisallowMultipleStatements | [ref]

Multiple statements are not allowed on a single line.

Valid: Two statements are spread out on two separate lines. Invalid: Two statements are combined onto one line.
$foo = 1;
$bar = 2;
$foo = 1; $bar = 2;

Generic.Formatting.MultipleStatementAlignment | [ref]

There should be one space on either side of an equals sign used to assign a value to a variable. In the case of a block of related assignments, more space may be inserted to promote readability.

Equals signs aligned Not aligned; harder to read
$shortVar        = (1 + 2);
$veryLongVarName = 'string';
$var             = foo($bar, $baz);
$shortVar = (1 + 2);
$veryLongVarName = 'string';
$var = foo($bar, $baz);
Equals signs aligned; only one space after longest var name Two spaces after longest var name
$shortVar       += 1;
$veryLongVarName = 1;
$shortVar        += 1;
$veryLongVarName  = 1;
Equals signs aligned Equals signs not aligned
$shortVar         = 1;
$veryLongVarName -= 1;
$shortVar        = 1;
$veryLongVarName -= 1;

Generic.Formatting.SpaceAfterCast | [ref]

Exactly one space is allowed after a cast.

Valid: A cast operator is followed by one space. Invalid: A cast operator is not followed by whitespace.
$foo = (string) 1;
$foo = (string)1;

Generic.Functions.CallTimePassByReference | [ref]

Call-time pass-by-reference is not allowed. It should be declared in the function definition.

Valid: Pass-by-reference is specified in the function definition. Invalid: Pass-by-reference is done in the call to a function.
function foo(&$bar)
{
    $bar++;
}

$baz = 1;
foo($baz);
function foo($bar)
{
    $bar++;
}

$baz = 1;
foo(&$baz);

Generic.Functions.FunctionCallArgumentSpacing | [ref]

Function arguments should have one space after a comma, and single spaces surrounding the equals sign for default values.

Valid: Single spaces after a comma. Invalid: No spaces after a comma.
function foo($bar, $baz)
{
}
function foo($bar,$baz)
{
}
Valid: Single spaces around an equals sign in function declaration. Invalid: No spaces around an equals sign in function declaration.
function foo($bar, $baz = true)
{
}
function foo($bar, $baz=true)
{
}

Generic.Functions.OpeningFunctionBraceKernighanRitchie | [ref]

Function declarations follow the "Kernighan/Ritchie style". The function brace is on the same line as the function declaration. One space is required between the closing parenthesis and the brace.

Valid: brace on same line Invalid: brace on next line
function fooFunction($arg1, $arg2 = '') {
    ...
}
function fooFunction($arg1, $arg2 = '')
{
    ...
}

Generic.NamingConventions.UpperCaseConstantName | [ref]

Constants should always be all-uppercase, with underscores to separate words.

Valid: all uppercase Invalid: mixed case
define('FOO_CONSTANT', 'foo');

class FooClass
{
    const FOO_CONSTANT = 'foo';
}
define('Foo_Constant', 'foo');

class FooClass
{
    const foo_constant = 'foo';
}

Generic.PHP.BacktickOperator | [ref]

Disallow the use of the backtick operator for execution of shell commands.


Generic.PHP.DeprecatedFunctions | [ref]

Deprecated functions should not be used.

Valid: A non-deprecated function is used. Invalid: A deprecated function is used.
$foo = explode('a', $bar);
$foo = split('a', $bar);

Generic.PHP.DisallowAlternativePHPTags | [ref]

Always use <?php ?> to delimit PHP code, do not use the ASP <% %> style tags nor the <script language="php"></script> tags. This is the most portable way to include PHP code on differing operating systems and setups.


Generic.PHP.DisallowShortOpenTag | [ref]

Always use <?php ?> to delimit PHP code, not the <? ?> shorthand. This is the most portable way to include PHP code on differing operating systems and setups.


Generic.PHP.DiscourageGoto | [ref]

Discourage the use of the PHP goto language construct.


Generic.PHP.ForbiddenFunctions | [ref]

The forbidden functions sizeof() and delete() should not be used.

Valid: count() is used in place of sizeof(). Invalid: sizeof() is used.
$foo = count($bar);
$foo = sizeof($bar);

Generic.PHP.LowerCaseConstant | [ref]

The true, false and null constants must always be lowercase.

Valid: lowercase constants Invalid: uppercase constants
if ($var === false || $var === null) {
    $var = true;
}
if ($var === FALSE || $var === NULL) {
    $var = TRUE;
}

Generic.PHP.LowerCaseKeyword | [ref]

All PHP keywords should be lowercase.

Valid: Lowercase array keyword used. Invalid: Non-lowercase array keyword used.
$foo = array();
$foo = Array();

Generic.PHP.LowerCaseType | [ref]

All PHP types used for parameter type and return type declarations should be lowercase.

Valid: Lowercase type declarations used. Invalid: Non-lowercase type declarations used.
function myFunction(int $foo) : string {
}
function myFunction(Int $foo) : STRING {
}
Valid: Lowercase type used. Invalid: Non-lowercase type used.
$foo = (bool) $isValid;
$foo = (BOOL) $isValid;

Generic.PHP.Syntax | [ref]

The code should use valid PHP syntax.

Valid: No PHP syntax errors. Invalid: Code contains PHP syntax errors.
echo "Hello!";
$array = [1, 2, 3];
echo "Hello!" // Missing semicolon.
$array = [1, 2, 3; // Missing closing bracket.

Generic.Strings.UnnecessaryStringConcat | [ref]

Strings should not be concatenated together.

Valid: A string can be concatenated with an expression. Invalid: Strings should not be concatenated together.
echo '5 + 2 = ' . (5 + 2);
echo 'Hello' . ' ' . 'World';

Generic.VersionControl.GitMergeConflict | [ref]


Generic.WhiteSpace.ArbitraryParenthesesSpacing | [ref]

Arbitrary sets of parentheses should have no spaces inside.

Valid: no spaces on the inside of a set of arbitrary parentheses. Invalid: spaces or new lines on the inside of a set of arbitrary parentheses.
$a = (null !== $extra);
$a = ( null !== $extra );

$a = (
    null !== $extra
);

Generic.WhiteSpace.DisallowSpaceIndent | [ref]

Tabs should be used for indentation instead of spaces.


Generic.WhiteSpace.IncrementDecrementSpacing | [ref]

There should be no whitespace between variables and increment/decrement operators.

Valid: No whitespace between variables and increment/decrement operators. Invalid: Whitespace between variables and increment/decrement operators.
++$i;
--$i['key']['id'];
ClassName::$prop++;
$obj->prop--;
++ $i;
--   $i['key']['id'];
ClassName::$prop    ++;
$obj->prop
--;

Generic.WhiteSpace.LanguageConstructSpacing | [ref]

Language constructs that can be used without parentheses, must have a single space between the language construct keyword and its content.

Valid: Single space after language construct. Invalid: No space, more than one space or newline after language construct.
echo 'Hello, World!';
throw new Exception();
return $newLine;
echo'Hello, World!';
throw   new   Exception();
return
$newLine;
Valid: Single space between yield and from. Invalid: No space, more than one space or newline between yield and from.
yield from [1, 2, 3];
yieldfrom [1, 2, 3];
yield  from [1, 2, 3];
yield
from [1, 2, 3];

Generic.WhiteSpace.ScopeIndent | [ref]

Indentation for control structures, classes, and functions should be 4 spaces per level.

Valid: 4 spaces are used to indent a control structure. Invalid: 8 spaces are used to indent a control structure.
if ($test) {
    $var = 1;
}
if ($test) {
        $var = 1;
}

Generic.WhiteSpace.SpreadOperatorSpacingAfter | [ref]

There should be no space between the spread operator and the variable/function call it applies to.

Valid: No space between the spread operator and the variable/function call it applies to. Invalid: space found between the spread operator and the variable/function call it applies to.
function foo(&...$spread) {
    bar(...$spread);

    bar(
        [...$foo],
        ...array_values($keyedArray)
    );
}
function bar(... $spread) {
    bar(...
        $spread
    );

    bar(
        [...  $foo ],.../*comment*/array_values($keyedArray)
    );
}

Modernize.FunctionCalls.Dirname | [ref]

PHP >= 5.3: Usage of dirname(FILE) can be replaced with DIR.

Valid: Using __DIR__. Invalid: dirname(__FILE__).
$path = __DIR__;
$path = dirname(__FILE__);
Valid: Using dirname() with the $levels parameter. Invalid: Nested function calls to dirname().
$path = dirname($file, 3);
$path = dirname(dirname(dirname($file)));

NormalizedArrays.Arrays.ArrayBraceSpacing | [ref]

There should be no space between the "array" keyword and the array open brace.

Valid: No space between the keyword and the open brace. Invalid: Space between the keyword and the open brace.
$args = array(1, 2);
$args = array  (1, 2);
Valid: No space between the braces. Invalid: Space between the braces.
$args = array();

$args = [];
$args = array( );

$args = [  ];
Valid: No space on the inside of the braces. Invalid: Space on the inside of the braces.
$args = array(1, 2);

$args = [1, 2];
$args = array( 1, 2 );

$args = [  1, 2  ];
Valid: One new line after the open brace and before the close brace. Invalid: No new lines after the open brace and/or before the close brace.
$args = array(
    1,
    2
);

$args = [
    1,
    2
];
$args = array(1,
    2);

$args = [1,
    2];

NormalizedArrays.Arrays.CommaAfterLast | [ref]

For single-line arrays, there should be no comma after the last array item.

  However, for multi-line arrays, there *should* be a comma after the last array item.
Valid: Single-line array without a comma after the last item Invalid: Single-line array with a comma after the last item
$args = array(1, 2, 3);
$args = array(1, 2, 3, );
Valid: Multi-line array with a comma after the last item Invalid: Multi-line array without a comma after the last item
$args = [
    1 => 'foo',
    2 => 'bar',
];
$args = [
    1 => 'foo',
    2 => 'bar'
];

PEAR.Files.IncludingFile | [ref]

Anywhere you are unconditionally including a class file, use require_once. Anywhere you are conditionally including a class file (for example, factory methods), use include_once. Either of these will ensure that class files are included only once. They share the same file list, so you don't need to worry about mixing them - a file included with require_once will not be included again by include_once. Note that include_once and require_once are statements, not functions. Parentheses should not surround the subject filename.

Valid: used as statement Invalid: used as function
require_once 'PHP/CodeSniffer.php';
require_once('PHP/CodeSniffer.php');

PEAR.Functions.FunctionCallSignature | [ref]

Functions should be called with no spaces between the function name, the opening parenthesis, and the first parameter; and no space between the last parameter, the closing parenthesis, and the semicolon.

Valid: spaces between parameters Invalid: additional spaces used
$var = foo($bar, $baz, $quux);
$var = foo ( $bar, $baz, $quux ) ;

PEAR.NamingConventions.ValidClassName | [ref]

Classes should be given descriptive names. Avoid using abbreviations where possible. Class names should always begin with an uppercase letter. The PEAR class hierarchy is also reflected in the class name, each level of the hierarchy separated with a single underscore.

Examples of valid class names Examples of invalid class names
Log
Net_Finger
HTML_Upload_Error
log
NetFinger
HTML-Upload-Error

PSR2.Classes.ClassDeclaration | [ref]

There should be exactly 1 space between the abstract or final keyword and the class keyword and between the class keyword and the class name. The extends and implements keywords, if present, must be on the same line as the class name. When interfaces implemented are spread over multiple lines, there should be exactly 1 interface mentioned per line indented by 1 level. The closing brace of the class must go on the first line after the body of the class and must be on a line by itself.

Valid: Correct spacing around class keyword. Invalid: 2 spaces used around class keyword.
abstract class Foo
{
}
abstract  class  Foo
{
}

PSR2.Classes.PropertyDeclaration | [ref]

Property names should not be prefixed with an underscore to indicate visibility. Visibility should be used to declare properties rather than the var keyword. Only one property should be declared within a statement. The static declaration must come after the visibility declaration.

Valid: Correct property naming. Invalid: An underscore prefix used to indicate visibility.
class Foo
{
    private $bar;
}
class Foo
{
    private $_bar;
}
Valid: Visibility of property declared. Invalid: Var keyword used to declare property.
class Foo
{
    private $bar;
}
class Foo
{
    var $bar;
}
Valid: One property declared per statement. Invalid: Multiple properties declared in one statement.
class Foo
{
    private $bar;
    private $baz;
}
class Foo
{
    private $bar, $baz;
}
Valid: If declared as static, the static declaration must come after the visibility declaration. Invalid: Static declaration before the visibility declaration.
class Foo
{
    public static $bar;
    private $baz;
}
class Foo
{
    static protected $bar;
}

PSR2.ControlStructures.ElseIfDeclaration | [ref]

PHP's elseif keyword should be used instead of else if.

Valid: Single word elseif keyword used. Invalid: Separate else and if keywords used.
if ($foo) {
    $var = 1;
} elseif ($bar) {
    $var = 2;
}
if ($foo) {
    $var = 1;
} else if ($bar) {
    $var = 2;
}

PSR2.ControlStructures.SwitchDeclaration | [ref]

Case statements should be indented 4 spaces from the switch keyword. It should also be followed by a space. Colons in switch declarations should not be preceded by whitespace. Break statements should be indented 4 more spaces from the case statement. There must be a comment when falling through from one case into the next.

Valid: Case statement indented correctly. Invalid: Case statement not indented 4 spaces.
switch ($foo) {
    case 'bar':
        break;
}
switch ($foo) {
case 'bar':
    break;
}
Valid: Case statement followed by 1 space. Invalid: Case statement not followed by 1 space.
switch ($foo) {
    case 'bar':
        break;
}
switch ($foo) {
    case'bar':
        break;
}
Valid: Colons not prefixed by whitespace. Invalid: Colons prefixed by whitespace.
switch ($foo) {
    case 'bar':
        break;
    default:
        break;
}
switch ($foo) {
    case 'bar' :
        break;
    default :
        break;
}
Valid: Break statement indented correctly. Invalid: Break statement not indented 4 spaces.
switch ($foo) {
    case 'bar':
        break;
}
switch ($foo) {
    case 'bar':
    break;
}
Valid: Comment marking intentional fall-through. Invalid: No comment marking intentional fall-through.
switch ($foo) {
    case 'bar':
    // no break
    default:
        break;
}
switch ($foo) {
    case 'bar':
    default:
        break;
}

PSR2.Files.ClosingTag | [ref]

Checks that the file does not end with a closing tag.

Valid: Closing tag not used. Invalid: Closing tag used.
<?php
echo 'Foo';
<?php
echo 'Foo';
?>

PSR2.Files.EndFileNewline | [ref]

PHP Files should end with exactly one newline.


PSR2.Methods.FunctionClosingBrace | [ref]

Checks that the closing brace of a function goes directly after the body.

Valid: Closing brace directly follows the function body. Invalid: Blank line between the function body and the closing brace.
function foo()
{
    echo 'foo';
}
function foo()
{
    echo 'foo';

}

PSR2.Methods.MethodDeclaration | [ref]

Method names should not be prefixed with an underscore to indicate visibility. The static keyword, when present, should come after the visibility declaration, and the final and abstract keywords should come before.

Valid: Correct method naming. Invalid: An underscore prefix used to indicate visibility.
class Foo
{
    private function bar()
    {
    }
}
class Foo
{
    private function _bar()
    {
    }
}
Valid: Correct ordering of method prefixes. Invalid: static keyword used before visibility and final used after.
class Foo
{
    final public static function bar()
    {
    }
}
class Foo
{
    static public final function bar()
    {
    }
}

PSR2.Namespaces.NamespaceDeclaration | [ref]

There must be one blank line after the namespace declaration.

Valid: One blank line after the namespace declaration. Invalid: No blank line after the namespace declaration.
namespace \Foo\Bar;

use \Baz;
namespace \Foo\Bar;
use \Baz;

PSR12.Classes.ClassInstantiation | [ref]

When instantiating a new class, parenthesis MUST always be present even when there are no arguments passed to the constructor.

Valid: Parenthesis used. Invalid: Parenthesis not used.
new Foo();
new Foo;

PSR12.Files.FileHeader | [ref]


PSR12.Functions.NullableTypeDeclaration | [ref]

In nullable type declarations there MUST NOT be a space between the question mark and the type.

Valid: no whitespace used. Invalid: superfluous whitespace used.
public function functionName(
    ?string $arg1,
    ?int $arg2
): ?string {
}
public function functionName(
    ? string $arg1,
    ? int $arg2
): ? string {
}
Valid: no unexpected characters. Invalid: unexpected characters used.
public function foo(?int $arg): ?string
{
}
public function bar(? /* comment */ int $arg): ?
    // nullable for a reason
    string
{
}

PSR12.Functions.ReturnTypeDeclaration | [ref]

For function and closure return type declarations, there must be one space after the colon followed by the type declaration, and no space before the colon.

The colon and the return type declaration have to be on the same line as the argument list closing parenthesis.
Valid: A single space between the colon and type in a return type declaration. Invalid: No space between the colon and the type in a return type declaration.
$closure = function ( $arg ): string {
   // Closure body.
};
$closure = function ( $arg ):string {
   // Closure body.
};
Valid: No space before the colon in a return type declaration. Invalid: One or more spaces before the colon in a return type declaration.
function someFunction( $arg ): string {
   // Function body.
};
function someFunction( $arg )   : string {
   // Function body.
};

PSR12.Keywords.ShortFormTypeKeywords | [ref]

Short form of type keywords MUST be used i.e. bool instead of boolean, int instead of integer etc.

Valid: Short form type used. Invalid: Long form type type used.
$foo = (bool) $isValid;
$foo = (boolean) $isValid;

PSR12.Traits.UseDeclaration | [ref]


Squiz.Classes.SelfMemberReference | [ref]

The self keyword should be used instead of the current class name, should be lowercase, and should not have spaces before or after it.

Valid: Lowercase self used. Invalid: Uppercase self used.
self::foo();
SELF::foo();
Valid: Correct spacing used. Invalid: Incorrect spacing used.
self::foo();
self :: foo();
Valid: Self used as reference. Invalid: Local class name used as reference.
class Foo
{
    public static function bar()
    {
    }

    public static function baz()
    {
        self::bar();
    }
}
class Foo
{
    public static function bar()
    {
    }

    public static function baz()
    {
        Foo::bar();
    }
}

Squiz.Commenting.BlockComment | [ref]


Squiz.Commenting.ClassComment | [ref]


Squiz.Commenting.ClosingDeclarationComment | [ref]


Squiz.Commenting.DocCommentAlignment | [ref]

The asterisks in a doc comment should align, and there should be one space between the asterisk and tags.

Valid: Asterisks are aligned. Invalid: Asterisks are not aligned.
/**
 * @see foo()
 */
/**
  * @see foo()
*/
Valid: One space between asterisk and tag. Invalid: Incorrect spacing used.
/**
 * @see foo()
 */
/**
 *  @see foo()
 */

Squiz.Commenting.EmptyCatchComment | [ref]


Squiz.Commenting.FileComment | [ref]


Squiz.Commenting.FunctionComment | [ref]


Squiz.Commenting.FunctionCommentThrowTag | [ref]

If a function throws any exceptions, they should be documented in a @throws tag.

Valid: @throws tag used. Invalid: No @throws tag used for throwing function.
/**
 * @throws Exception all the time
 * @return void
 */
function foo()
{
    throw new Exception('Danger!');
}
/**
 * @return void
 */
function foo()
{
    throw new Exception('Danger!');
}

Squiz.Commenting.InlineComment | [ref]


Squiz.Commenting.VariableComment | [ref]


Squiz.ControlStructures.ControlSignature | [ref]


Squiz.Functions.FunctionDeclarationArgumentSpacing | [ref]


Squiz.Functions.FunctionDuplicateArgument | [ref]

All PHP built-in functions should be lowercased when called.

Valid: Lowercase function call. Invalid: isset not called as lowercase.
if (isset($foo)) {
    echo $foo;
}
if (isSet($foo)) {
    echo $foo;
}

Squiz.Functions.MultiLineFunctionDeclaration | [ref]


Squiz.Operators.IncrementDecrementUsage | [ref]


Squiz.Operators.ValidLogicalOperators | [ref]


Squiz.PHP.CommentedOutCode | [ref]


Squiz.PHP.DisallowMultipleAssignments | [ref]


Squiz.PHP.DisallowSizeFunctionsInLoops | [ref]


Squiz.PHP.EmbeddedPhp | [ref]


Squiz.PHP.Eval | [ref]


Squiz.PHP.NonExecutableCode | [ref]


Squiz.Scope.MethodScope | [ref]


Squiz.Strings.ConcatenationSpacing | [ref]


Squiz.Strings.DoubleQuoteUsage | [ref]


Squiz.WhiteSpace.CastSpacing | [ref]

Casts should not have whitespace inside the parentheses.

Valid: No spaces. Invalid: Whitespace used inside parentheses.
$foo = (int)'42';
$foo = ( int )'42';

Squiz.WhiteSpace.ScopeKeywordSpacing | [ref]

The php keywords static, public, private, and protected should have one space after them.

Valid: A single space following the keywords. Invalid: Multiple spaces following the keywords.
public static function foo()
{
}
public  static  function foo()
{
}

Squiz.WhiteSpace.SemicolonSpacing | [ref]

Semicolons should not have spaces before them.

Valid: No space before the semicolon. Invalid: Space before the semicolon.
echo "hi";
echo "hi" ;

Squiz.WhiteSpace.SuperfluousWhitespace | [ref]


Universal.Arrays.DisallowShortArraySyntax | [ref]

The array keyword must be used to define arrays.

Valid: Using long form array syntax. Invalid: Using short array syntax.
$arr = array(
    'foo' => 'bar',
);
$arr = [
    'foo' => 'bar',
];

Universal.Arrays.DuplicateArrayKey | [ref]

When a second array item with the same key is declared, it will overwrite the first. This sniff detects when this is happening in array declarations.

Valid: Arrays with unique keys. Invalid: Array with duplicate keys.
$args = array(
    'foo' => 22,
    'bar' => 25,
    'baz' => 28,
);

$args = array(
    22,
    25,
    2 => 28,
);
$args = array(
    'foo' => 22,
    'bar' => 25,
    'bar' => 28,
);

$args = array(
    22,
    25,
    1 => 28,
);

Universal.Classes.ModifierKeywordOrder | [ref]

Requires that class modifier keywords consistently use the same keyword order.

By default the expected order is &quot;abstract/final readonly&quot;, but this can be changed via the sniff configuration.
Valid: Modifier keywords ordered correctly. Invalid: Modifier keywords in reverse order.
final readonly class Foo {}
abstract readonly class Bar {}
readonly final class Foo {}
readonly abstract class Bar {}

Universal.Classes.RequireAnonClassParentheses | [ref]

Require the use of parentheses when declaring an anonymous class.

Valid: Anonymous class with parentheses. Invalid: Anonymous class without parentheses.
$anon = new class() {};
$anon = new class {};

Universal.CodeAnalysis.ConstructorDestructorReturn | [ref]

A class constructor/destructor can not have a return type declarations. This would result in a fatal error.

Valid: no return type declaration. Invalid: return type declaration.
class Foo {
    public function __construct() {}
}
class Foo {
    public function __construct(): int {}
}
Valid: class constructor/destructor doesn't return anything. Invalid: class constructor/destructor returns a value.
class Foo {
    public function __construct() {
        // Do something.
    }

    public function __destruct() {
        // Do something.
        return;
    }
}
class Foo {
    public function __construct() {
        // Do something.
        return $this;
    }

    public function __destruct() {
        // Do something.
        return false;
    }
}

Universal.CodeAnalysis.ForeachUniqueAssignment | [ref]

When a foreach control structure uses the same variable for both the $key as well as the $value assignment, the key will be disregarded and be inaccessible and the variable will contain the value. Mix in reference assignments and the behaviour becomes even more unpredictable.

This is a coding error. Either use unique variables for the key and the value or don&#039;t assign the key.
Valid: using unique variables. Invalid: using the same variable for both the key as well as the value.
foreach ($array as $k => $v ) {}
foreach ($array as $k => $k ) {}

Universal.CodeAnalysis.NoDoubleNegative | [ref]

Detects double negation in code, which is effectively the same as a boolean cast, but with a much higher cognitive load.

Valid: using singular negation or a boolean cast. Invalid: using double negation (or more).
$var = $a && ! $b;

if((bool) callMe($a)) {}
$var = $a && ! ! $b;

if(! ! ! callMe($a)) {}

Universal.CodeAnalysis.NoEchoSprintf | [ref]

Detects use of echo [v]sprintf(...);. Use [v]printf() instead.

Valid: using [v]printf() or echo with anything but [v]sprintf(). Invalid: using echo [v]sprintf().
printf('text %s text', $var);
echo callMe('text %s text', $var);
echo sprintf('text %s text', $var);
echo vsprintf('text %s text', [$var]);

Universal.CodeAnalysis.StaticInFinalClass | [ref]

When a class is declared as final, using the static keyword for late static binding is unnecessary and redundant. This rule also covers using static in a comparison with instanceof, using static for class instantiations or as a return type.

`self` should be used instead.

This applies to final classes, anonymous classes (final by nature) and enums (final by design).
Valid: Using 'self' in a final OO construct. Invalid: Using 'static' in a final OO construct.
final class Foo
{
    public function myMethod($param) : self
    {
        $var = self::functionCall();
        $var = $obj instanceof self;
        $var = new self;
    }
}
$anon = new class {
    public function myMethod(
    ): int|static|false {
        $var = static::$prop;
        $var = $obj instanceof static;
        $var = new static();
    }
};

Universal.Constants.LowercaseClassResolutionKeyword | [ref]

The "class" keyword when used for class name resolution, i.e. ::class, must be in lowercase.

Valid: using lowercase. Invalid: using uppercase or mixed case.
echo MyClass::class;
echo MyClass::CLASS;

Universal.Constants.ModifierKeywordOrder | [ref]

Requires that constant modifier keywords consistently use the same keyword order.

By default the expected order is &quot;final visibility&quot;, but this can be changed via the sniff configuration.
Valid: Modifier keywords ordered correctly. Invalid: Modifier keywords in reverse order.
class CorrectOrder {
    final public const FOO = 'foo';
}
class IncorrectOrder {
    #[SomeAttribute]
    protected final const BAR = 'foo';
}

Universal.Constants.UppercaseMagicConstants | [ref]

The PHP native __...__ magic constant should be in uppercase.

Valid: using uppercase. Invalid: using lowercase or mixed case.
echo __LINE__;
include __DIR__ . '/file.php';
echo __NameSpace__;
include dirname(__file__) . '/file.php';

Universal.ControlStructures.DisallowLonelyIf | [ref]

Disallows if statements as the only statement in an else block.

If an `if` statement is the only statement in the `else` block, use `elseif` instead.
Valid: use of elseif or if followed by another statement. Invalid: lonely if in an else block.
if ($foo) {
    // ...
} elseif ($bar) {
    // ...
}

if ($foo) {
    // ...
} else {
    if ($bar) {
        // ...
    }

    doSomethingElse();

}
if ($foo) {
    // ...
} else {
    if ($bar) {
        // ...
    } else {
        // ...
    }
}

Universal.Files.SeparateFunctionsFromOO | [ref]

A file should either declare (global/namespaced) functions or declare OO structures, but not both.

Nested function declarations, i.e. functions declared within a function/method will be disregarded for the purposes of this sniff.
The same goes for anonymous classes, closures and arrow functions.
Valid: Files containing only functions or only OO. Invalid: File containing both OO structure declarations as well as function declarations.
// Valid1.php
<?php
class Bar {
    public function foo() {}
}

// Valid2.php
<?php
function foo() {}
function bar() {}
function baz() {}
// Invalid.php
<?php
function foo() {}

class Bar {
    public function foo() {}
}

function bar() {}
function baz() {}

Universal.Namespaces.DisallowCurlyBraceSyntax | [ref]

Namespace declarations using the curly brace syntax are not allowed.

Valid: Namespace declaration without braces. Invalid: Namespace declaration with braces.
namespace Vendor\Project\Sub;

// Code
namespace Vendor\Project\Scoped {
    // Code.
}

Universal.Namespaces.DisallowDeclarationWithoutName | [ref]

Namespace declarations without a namespace name are not allowed.

Valid: Named namespace declaration. Invalid: Namespace declaration without a name (=global namespace).
namespace Vendor\Name {
}
namespace {
}

Universal.Namespaces.OneDeclarationPerFile | [ref]

There should be only one namespace declaration per file.

Valid: One namespace declaration in a file. Invalid: Multiple namespace declarations in a file.
namespace Vendor\Project\Sub;
namespace Vendor\Project\Sub\A {
}

namespace Vendor\Project\Sub\B {
}

Universal.NamingConventions.NoReservedKeywordParameterNames | [ref]

It is recommended not to use reserved keywords as parameter names as this can become confusing when people use them in function calls using named parameters.

Valid: parameter names do not use reserved keywords. Invalid: parameter names use reserved keywords.
function foo( $input, $description ) {}
function foo( $string, $echo = true ) {}

Universal.Operators.DisallowShortTernary | [ref]

Using short ternaries is not allowed.

While short ternaries are useful when used correctly, the principle of them is often misunderstood and they are more often than not used incorrectly, leading to hard to debug issues and/or PHP warnings/notices.
Valid: Full ternary. Invalid: Short ternary.
echo !empty($a) ? $a : 'default';
echo !empty($a) ?: 'default';
echo $a ? : 'default';

Universal.Operators.DisallowStandalonePostIncrementDecrement | [ref]

In a stand-alone in/decrement statement, pre-in/decrement should always be favoured over post-in/decrement.

This reduces the chance of bugs when code gets moved around.
Valid: Pre-in/decrement in a stand-alone statement. Invalid: Post-in/decrement in a stand-alone statement.
++$i;
--$j;
$i++;
$j--;
Valid: Single in/decrement operator in a stand-alone statement. Invalid: Multiple in/decrement operators in a stand-alone statement.
++$i;
--$i++++;

Universal.Operators.StrictComparisons | [ref]

Using loose comparisons is not allowed.

Loose comparisons will type juggle the values being compared, which often results in bugs.
Valid: Using strict comparisons. Invalid: Using loose comparisons.
if ($var === 'text') {}

if ($var !== true) {}
if ($var == 'text') {}

if ($var != true) {}

Universal.Operators.TypeSeparatorSpacing | [ref]

There should be no spacing around the union type separator or the intersection type separator.

This applies to all locations where type declarations can be used, i.e. property types, parameter types and return types.
Valid: No space around the separators. Invalid: Space around the separators.
function foo(
    int|string $paramA,
    TypeA&TypeB $paramB
): int|false {}
function foo(
    int | string $paramA,
    TypeA & TypeB $paramB
): int
   |
   false {}

Universal.PHP.LowercasePHPTag | [ref]

Enforces that the PHP open tag is lowercase.

Valid: Lowercase open tag. Invalid: Uppercase open tag.
<?php
echo 'hello!';
<?PHP
echo 'hello!';

Universal.UseStatements.DisallowMixedGroupUse | [ref]

Disallow group use statements which combine imports for namespace/OO, functions and/or constants in one statement.

Valid: Single type group use statements. Invalid: Mixed group use statement.
use Some\NS\ {
    ClassName,
    AnotherClass,
};
use function Some\NS\ {
    SubLevel\functionName,
    SubLevel\AnotherFunction,
};
use const Some\NS\ {
    Constants\MY_CONSTANT as SOME_CONSTANT,
};
use Some\NS\ {
    ClassName,
    function SubLevel\functionName,
    const MY_CONSTANT as SOME_CONSTANT,
    function SubLevel\AnotherName,
    AnotherLevel,
};

Universal.UseStatements.KeywordSpacing | [ref]

Enforce a single space after the use, function, const keywords and both before and after the as keyword in import use statements.

Valid: Single space used around keywords. Invalid: Incorrect spacing used around keywords.
use function strpos;
use const PHP_EOL as MY_EOL;
use    function   strpos;
use
  const
  PHP_EOL
  as
  MY_EOL;

Universal.UseStatements.LowercaseFunctionConst | [ref]

function and const keywords in import use statements should be in lowercase.

Valid: Lowercase keywords. Invalid: Non-lowercase keywords.
use function strpos;
use const PHP_EOL;
use Function strpos;
use CONST PHP_EOL;

Universal.UseStatements.NoLeadingBackslash | [ref]

Import use statements must never begin with a leading backslash as they should always be fully qualified.

Valid: Import use statement without leading backslash. Invalid: Import use statement with leading backslash.
use Package\ClassName;
use \Package\ClassName;

Universal.UseStatements.NoUselessAliases | [ref]

Detects useless aliases for import use statements.

Aliasing something to the same name as the original construct is considered useless.
Note: as OO and function names in PHP are case-insensitive, aliasing to the same name, using a different case is also considered useless.
Valid: Import use statement with an alias to a different name. Invalid: Import use statement with an alias to the same name.
use Vendor\Package\ClassName as AnotherName;
use function functionName as my_function;
use const SOME_CONSTANT as MY_CONSTANT;
use Vendor\Package\ClassName as ClassName;
use function functionName as FunctionName;
use const SOME_CONSTANT as SOME_CONSTANT;

Universal.WhiteSpace.AnonClassKeywordSpacing | [ref]

Checks the spacing between the "class" keyword and the open parenthesis for anonymous classes with parentheses.

The desired amount of spacing is configurable and defaults to no space.
Valid: No space between the class keyword and the open parenthesis. Invalid: Space between the class keyword and the open parenthesis.
$foo = new class($param)
{
    public function __construct($p) {}
};
$foo = new class ($param)
{
    public function __construct($p) {}
};

Universal.WhiteSpace.CommaSpacing | [ref]

There should be no space before a comma and exactly one space, or a new line, after a comma.

The sniff makes the following exceptions to this rule:
1. A comma preceded or followed by a parenthesis, curly or square bracket.
   These will not be flagged to prevent conflicts with sniffs handling spacing around braces.
2. A comma preceded or followed by another comma, like for skipping items in a list assignment.
   These will not be flagged.
3. A comma preceded by a non-indented heredoc/nowdoc closer.
   In that case, unless the `php_version` config directive is set to a version higher than PHP 7.3.0,
   a new line before will be enforced to prevent parse errors on PHP &lt; 7.3.
Valid: Correct spacing. Invalid: Incorrect spacing.
isset($param1, $param2, $param3);

function_call(
    $param1,
    $param2,
    $param3
);

$array = array($item1, $item2, $item3);
$array = [
    $item1,
    $item2,
];

list(, $a, $b,,) = $array;
list(
    ,
    $a,
    $b,
) = $array;
unset($param1  ,   $param2,$param3);

function_call(
    $a
    ,$b
    ,$c
);

$array = array($item1,$item2  ,  $item3);
$array = [
    $item1,
    $item2  ,
];

list( ,$a, $b  ,,) = $array;
list(
    ,
    $a,
    $b  ,
) = $array;
Valid: Comma after the code. Invalid: Comma after a trailing comment.
function_call(
    $param1, // Comment.
    $param2, /* Comment. */
);
function_call(
    $param1 // Comment.
    ,
    $param2 /* Comment. */,
);

Universal.WhiteSpace.DisallowInlineTabs | [ref]

Spaces must be used for mid-line alignment.

Valid: Spaces used for alignment. Invalid: Tabs used for alignment.
$title[space]= 'text';
$text[space][space]= 'more text';
$title[tab]= 'text';
$text[tab]= 'more text';

Universal.WhiteSpace.PrecisionAlignment | [ref]

Detects when the indentation is not a multiple of a tab-width, i.e. when precision alignment is used.

Valid: indentation equals (a multiple of) the tab width. Invalid: precision alignment used, indentation does not equal (a multiple of) the tab width.
// Code samples presume tab width = 4.
[space][space][space][space]$foo = 'bar';

[tab]$foo = 'bar';
// Code samples presume tab width = 4.
[space][space]$foo = 'bar';

[tab][space]$foo = 'bar';

WordPress.Arrays.ArrayDeclarationSpacing | [ref]


WordPress.Arrays.ArrayIndentation | [ref]

The array closing bracket indentation should line up with the start of the content on the line containing the array opener.

Valid: Closing bracket lined up correctly Invalid: Closing bracket lined up incorrectly
$args = array(
    'post_id' => 22,
);
$args = array(
    'post_id' => 22,
        );
Valid: Correctly indented array Invalid: Indented incorrectly; harder to read.
$args = array(
    'post_id'       => 22,
    'comment_count' => array(
        'value'   => 25,
        'compare' => '>=',
    ),
    'post_type' => array(
        'post',
        'page',
    ),
);
$args = array(
    'post_id'       => 22,
    'comment_count' => array(
    'value'   => 25,
    'compare' => '>=',
    ),
    'post_type' => array(
    'post',
    'page',
    ),
);
Valid: Subsequent lines are indented correctly. Invalid: Subsequent items are indented before the first line item.
$args = array(
    'phrase' => 'start of phrase'
        . 'concatented additional phrase'
        . 'more text',
);
$args = array(
    'phrase' => 'start of phrase'
. 'concatented additional phrase'
. 'more text',
);
Valid: Opener and comma after closer are indented correctly Invalid: Opener is aligned incorrectly to match the closer. The comma does not align correctly with the array indentation.
$text = array(
    <<<EOD
    start of phrase
    concatented additional phrase
    more text
EOD
    ,
);
$text = array(
<<<EOD
    start of phrase
    concatented additional phrase
    more text
EOD
,
);

WordPress.Arrays.ArrayKeySpacingRestrictions | [ref]

When referring to array items, only include a space around the index if it is a variable or the key is concatenated.

Valid: Correct spacing around the index keys Invalid: Incorrect spacing around the index keys
$post       = $posts[ $post_id ];
$post_title = $post[ 'concatenated' . $title ];
$post       = $posts[ HOME_PAGE ];
$post       = $posts[123];
$post_title = $post['post_title'];
$post       = $posts[$post_id];
$post_title = $post['concatenated' . $title ];
$post       = $posts[HOME_PAGE];
$post       = $posts[ 123 ];
$post_title = $post[ 'post_title' ];

WordPress.Arrays.MultipleStatementAlignment | [ref]

When declaring arrays, there should be one space on either side of a double arrow operator used to assign a value to a key.

Valid: correct spacing between the key and value. Invalid: No or incorrect spacing between the key and value.
$foo = array( 'cat' => 22 );
$bar = array( 'year' => $current_year );
$foo = array( 'cat'=>22 );
$bar = array( 'year'=>   $current_year );
Valid: Double arrow operators aligned Invalid: Not aligned; harder to read
$args = array(
    'cat'      => 22,
    'year'     => $current_year,
    'monthnum' => $current_month,
);
$args = array(
    'cat' => 22,
    'year' => $current_year,
    'monthnum' => $current_month,
);

WordPress.CodeAnalysis.AssignmentInTernaryCondition | [ref]


WordPress.CodeAnalysis.EscapedNotTranslated | [ref]

Text intended for translation needs to be wrapped in a localization function call. This sniff will help you find instances where text is escaped for output, but no localization function is called, even though an (unexpected) text domain argument is passed to the escape function.

Valid: esc_html__() used to translate and escape. Invalid: esc_html() used to only escape a string intended to be translated as well.
echo esc_html__( 'text', 'domain' );
echo esc_html( 'text', 'domain' );

WordPress.DateTime.CurrentTimeTimestamp | [ref]

Don't use current_time() to get a timestamp as it doesn't produce a Unix (UTC) timestamp, but a "WordPress timestamp", i.e. a Unix timestamp with current timezone offset.

Valid: using time() to get a Unix (UTC) timestamp. Invalid: using current_time() to get a Unix (UTC) timestamp.
$timestamp = time();
$timestamp = current_time( 'timestamp', true );
Valid: using current_time() with a non-timestamp format. Invalid: using current_time() to get a timezone corrected timestamp.
$timestamp = current_time( 'Y-m-d' );
$timestamp = current_time( 'U', false );

WordPress.DateTime.RestrictedFunctions | [ref]

The restricted functions date_default_timezone_set() and date() should not be used. Using the PHP native date_default_timezone_set() function isn't allowed, because WordPress Core needs the default time zone to be set to UTC for timezone calculations using the WP Core API to work correctly.

Valid: Using DateTime object. Invalid: Using date_default_timezone_set().
$date = new DateTime();
$date->setTimezone(
    new DateTimeZone( 'Europe/Amsterdam' )
);
date_default_timezone_set( 'Europe/Amsterdam' );
Valid: Using gmdate(). Invalid: Using date().
$last_updated = gmdate(
    'Y-m-d\TH:i:s',
    strtotime( $plugin['last_updated'] )
);
$last_updated = date(
    'Y-m-d\TH:i:s',
    strtotime( $plugin['last_updated'] )
);

WordPress.DB.DirectDatabaseQuery | [ref]


WordPress.DB.PreparedSQL | [ref]


WordPress.DB.PreparedSQLPlaceholders | [ref]


WordPress.DB.RestrictedClasses | [ref]


WordPress.DB.RestrictedFunctions | [ref]


WordPress.DB.SlowDBQuery | [ref]


WordPress.Files.FileName | [ref]


WordPress.NamingConventions.PrefixAllGlobals | [ref]

All globals terms must be prefixed with a theme/plugin specific term. Global terms include Namespace names, Class/Interface/Trait/Enum names (when not namespaced), Functions (when not namespaced or in an OO structure), Constants/Variable names declared in the global namespace, and Hook names.

A prefix must be distinct and unique to the plugin/theme, in order to prevent potential conflicts with other plugins/themes and with WordPress itself.

The prefix used for a plugin/theme may be chosen by the developers and should be defined in a custom PHPCS ruleset to allow for this sniff to verify that the prefix is consistently used.
Prefixes will be treated in a case-insensitive manner.
https://github.com/WordPress/WordPress-Coding-Standards/wiki/Customizable-sniff-properties#naming-conventions-prefix-everything-in-the-global-namespace
Valid: Using the prefix ECPT_ Invalid: non-prefixed code
define( 'ECPT_VERSION', '1.0' );

$ecpt_admin = new ECPT_Admin_Page();

class ECPT_Admin_Page {}

apply_filter(
    'ecpt_modify_content',
    $ecpt_content
);
define( 'PLUGIN_VERSION', '1.0' );

$admin = new Admin_Page();

class Admin_Page {}

apply_filter(
    'modify_content',
    $content
);
Valid: Using the prefix ECPT_ in namespaced code Invalid: using a non-prefixed namespace
namespace ECPT_Plugin\Admin;

// Constants declared using `const` will
// be namespaced and therefore prefixed.
const VERSION = 1.0;

// A class declared in a (prefixed) namespace
// is automatically prefixed.
class Admin_Page {}

// Variables in a namespaced file are not
// namespaced, so still need prefixing.
$ecpt_admin = new Admin_Page();

// Hook names are not subject to namespacing.
apply_filter(
    'ecpt_modify_content',
    $ecpt_content
);
namespace Admin;

// As the namespace is not prefixed, this
// is still bad.
const VERSION = 1.0;

// As the namespace is not prefixed, this
// is still bad.
class Admin_Page {}
Valid: Using the prefix mycoolplugin_ Invalid: Using a WordPress reserved prefix wp_
function mycoolplugin_save_post() {}
function wp_save_post() {}
Valid: Using the distinct prefix MyPlugin Invalid: Using a two-letter prefix My
interface MyPluginIsCool {}
interface My {}

WordPress.NamingConventions.ValidFunctionName | [ref]


WordPress.NamingConventions.ValidHookName | [ref]

Use lowercase letters in action and filter names. Separate words using underscores.

Valid: lowercase hook name. Invalid: mixed case hook name.
do_action( 'prefix_hook_name', $var );
do_action( 'Prefix_Hook_NAME', $var );
Valid: words separated by underscores. Invalid: using non-underscore characters to separate words.
apply_filters( 'prefix_hook_name', $var );
apply_filters( 'prefix\hook-name', $var );

WordPress.NamingConventions.ValidPostTypeSlug | [ref]

The post type slug used in register_post_type() must be between 1 and 20 characters.

Valid: short post type slug. Invalid: too long post type slug.
register_post_type(
    'my_short_slug',
    array()
);
register_post_type(
    'my_own_post_type_too_long',
    array()
);
Valid: no special characters in post type slug. Invalid: invalid characters in post type slug.
register_post_type(
    'my_post_type_slug',
    array()
);
register_post_type(
    'my/post/type/slug',
    array()
);
Valid: static post type slug. Invalid: dynamic post type slug.
register_post_type(
    'my_post_active',
    array()
);
register_post_type(
    "my_post_{$status}",
    array()
);
Valid: prefixed post slug. Invalid: using a reserved keyword as slug.
register_post_type(
    'prefixed_author',
    array()
);
register_post_type(
    'author',
    array()
);
Valid: custom prefix post slug. Invalid: using a reserved prefix.
register_post_type(
    'prefixed_author',
    array()
);
register_post_type(
    'wp_author',
    array()
);

WordPress.NamingConventions.ValidVariableName | [ref]


WordPress.PHP.DevelopmentFunctions | [ref]


WordPress.PHP.DiscouragedPHPFunctions | [ref]


WordPress.PHP.DontExtract | [ref]


WordPress.PHP.IniSet | [ref]

Using ini_set() and similar functions for altering PHP settings at runtime is discouraged. Changing runtime configuration might break other plugins and themes, and even WordPress itself.

Valid: ini_set() for a possibly breaking setting. Invalid: ini_set() for a possibly breaking setting.
// ini_set() should not be used.
ini_set( 'short_open_tag', 'off' );
Valid: WordPress functional alternative. Invalid: ini_set() to alter memory limits.
wp_raise_memory_limit();
ini_set( 'memory_limit', '256M' );

WordPress.PHP.NoSilencedErrors | [ref]


WordPress.PHP.POSIXFunctions | [ref]


WordPress.PHP.PregQuoteDelimiter | [ref]


WordPress.PHP.RestrictedPHPFunctions | [ref]


WordPress.PHP.StrictInArray | [ref]

When using functions which compare a value to a range of values in an array, make sure a strict comparison is executed.

Typically, this rule verifies function calls to the PHP native `in_array()`, `array_search()` and `array_keys()` functions pass the `$strict` parameter.
Valid: calling in_array() with the $strict parameter set to `true`. Invalid: calling in_array() without passing the $strict parameter.
$array = array( '1', 1, true );
if ( in_array( $value, $array, true ) ) {}
$array = array( '1', 1, true );
if ( in_array( $value, $array ) ) {}
Valid: calling array_search() with the $strict parameter set to `true`. Invalid: calling array_search() without passing the $strict parameter.
$key = array_search( 1, $array, true );
$key = array_search( 1, $array );
Valid: calling array_keys() with a $search_value and the $strict parameter set to `true`. Invalid: calling array_keys() with a $search_value without passing the $strict parameter.
$keys = array_keys( $array, $key, true );
$keys = array_keys( $array, $key );

WordPress.PHP.TypeCasts | [ref]


WordPress.PHP.YodaConditions | [ref]

When doing logical comparisons involving variables, the variable must be placed on the right side. All constants, literals, and function calls must be placed on the left side. If neither side is a variable, the order is unimportant.

Valid: The variable is placed on the right Invalid: The variable has been placed on the left
if ( true === $the_force ) {
    $victorious = you_will( $be );
}
if ( $the_force === false ) {
    $victorious = you_will_not( $be );
}

WordPress.Security.EscapeOutput | [ref]


WordPress.Security.NonceVerification | [ref]


WordPress.Security.PluginMenuSlug | [ref]


WordPress.Security.SafeRedirect | [ref]

wp_safe_redirect() should be used whenever possible to prevent open redirect vulnerabilities. One of the main uses of an open redirect vulnerability is to make phishing attacks more credible. In this case the user sees your (trusted) domain and might get redirected to an attacker controlled website aimed at stealing private information.

Valid: Redirect can only go to allowed domains. Invalid: Unsafe redirect, can be abused.
wp_safe_redirect( $location );
wp_redirect( $location );

WordPress.Security.ValidatedSanitizedInput | [ref]


WordPress.Utils.I18nTextDomainFixer | [ref]


WordPress.WhiteSpace.CastStructureSpacing | [ref]

A type cast should be preceded by whitespace. There is only one exception to this rule: when the cast is preceded by the spread operator there should be no space between the spread operator and the cast.

Valid: space before typecast. Invalid: no space before typecast.
$a = (int) '420';

// No space between spread operator and cast.
$a = function_call( ...(array) $mixed );
$a =(int) '420';

WordPress.WhiteSpace.ControlStructureSpacing | [ref]

Put one space on both sides of the opening and closing parentheses of control structures.

Valid: One space on each side of the open and close parentheses. Invalid: Incorrect spacing around the open and close parentheses.
while ( have_posts() ) {}

// For multi-line conditions,
// a new line is also accepted.
if ( true === $condition
    && $count > 10
) {}
// No spaces.
while(have_posts()){}

// Too much space.
while   (   have_posts()   )   {}
Valid: Open brace on the same line as the keyword/close parenthesis. Invalid: Open brace on a different line than the keyword/close parenthesis.
try {
    // Do something.
} catch (
    ExceptionA | ExceptionB $e
) {
}
try
{
    // Do something.
} catch ( Exception $e )
(
}
Valid: One space between the keyword/close parenthesis and the open brace. Invalid: Too much space between the keyword/close parenthesis and the open brace.
if ( $condition ) {
    // Do something.
}
if ( $condition )     {
    // Do something.
}
Valid: One space before the colon. Invalid: No space before the colon.
foreach ( $types as $type ) :
    // Do something.
endforeach;
foreach ( $types as $type ):
    // Do something.
endforeach;
Valid: No blank line between the consecutive close braces. Invalid: Blank line(s) between the consecutive close braces.
if ( $a === $b ) {
    if ( $something ) {
        // Do something.
    }
}
if ( $a === $b ) {
    if ( $something ) {
        // Do something.
    }


}
Valid: No blank lines at the start or end of the control structure body. Invalid: Blank line(s) at the start and end of the control structure body.
if ( $a === $b ) {
    echo $a;
}
if ( $a === $b ) {


    echo $a;


}

WordPress.WhiteSpace.ObjectOperatorSpacing | [ref]

The object operators (->, ?->, ::) should not have any spaces around them, though new lines are allowed except for use with the ::class constant.

Valid: No spaces around the object operator. Invalid: Whitespace surrounding the object operator.
$foo->bar();
$foo  ?->  bar();

WordPress.WhiteSpace.OperatorSpacing | [ref]

Always put one space on both sides of logical, comparison and concatenation operators. Always put one space after an assignment operator.

Valid: one space before and after an operator. Invalid: too much/little space.
if ( $a === $b && $b === $c ) {}
if ( ! $var ) {}
// Too much space.
if ( $a === $b   &&   $b ===      $c ) {}
if (  ! $var ) {}

// Too little space.
if ( $a===$b &&$b ===$c ) {}
if ( !$var ) {}
Valid: a new line instead of a space is okay too. Invalid: too much space after operator on new line.
if ( $a === $b
    && $b === $c
) {}
if ( $a === $b
    &&     $b === $c
) {}
Valid: one space after assignment operator. Invalid: too much/little space after assignment operator.
$a   = 'foo';
$all = 'foobar';
$a   =     'foo';
$all ='foobar';

WordPress.WP.AlternativeFunctions | [ref]


WordPress.WP.Capabilities | [ref]

Capabilities passed should be valid capabilities (custom capabilities can be added in the ruleset).

Valid: a WP native or registered custom user capability is used. Invalid: unknown/unsupported user capability is used.
if ( author_can( $post, 'manage_sites' ) ) { }
map_meta_cap( 'manage_site', $user->ID );
Valid: user capability is used. Invalid: user role is used instead of a capability.
add_options_page(
    esc_html__( 'Options', 'textdomain' ),
    esc_html__( 'Options', 'textdomain' ),
    'manage_options',
    'options_page_slug',
    'project_options_page_cb'
);
add_options_page(
    esc_html__( 'Options', 'textdomain' ),
    esc_html__( 'Options', 'textdomain' ),
    'author',
    'options_page_slug',
    'project_options_page_cb'
);
Valid: a WP native or registered custom user capability is used. Invalid: deprecated user capability is used.
if ( author_can( $post, 'read' ) ) { }
if ( author_can( $post, 'level_6' ) ) { }

WordPress.WP.CapitalPDangit | [ref]

The correct spelling of "WordPress" should be used in text strings, comments and object names.

In select cases, when part of an identifier or a URL, WordPress does not have to be capitalized.

Valid: WordPress is correctly capitalized. Invalid: WordPress is not correctly capitalized.
class WordPress_Example {

    /**
     * This function is about WordPress.
     */
    public function explain() {
        echo 'This is an explanation
            about WordPress.';
    }
}
class Wordpress_Example {

    /**
     * This function is about Wordpress.
     */
    public function explain() {
        echo 'This is an explanation
            about wordpress.';
    }
}

WordPress.WP.ClassNameCase | [ref]

It is strongly recommended to refer to WP native classes by their properly cased name.

Valid: reference to a WordPress native class name using the correct case. Invalid: reference to a WordPress native class name not using the correct case.
$obj = new WP_Query;
$obj = new wp_query;

WordPress.WP.CronInterval | [ref]

Cron schedules running more often than once every 15 minutes are discouraged. Crons running that frequently can negatively impact the performance of a site.

Valid: Cron schedule is created to run once every hour. Invalid: Cron schedule is added to run more than once per 15 minutes.
function adjust_schedules( $schedules ) {
    $schedules['every_hour'] = array(
        'interval' => HOUR_IN_SECONDS,
        'display'  => __( 'Every hour' )
    );
    return $schedules;
}

add_filter(
    'cron_schedules',
    'adjust_schedules'
);
function adjust_schedules( $schedules ) {
    $schedules['every_9_mins'] = array(
        'interval' => 9 * 60,
        'display'  => __( 'Every 9 minutes' )
    );
    return $schedules;
}

add_filter(
    'cron_schedules',
    'adjust_schedules'
);

WordPress.WP.DeprecatedClasses | [ref]

Please refrain from using deprecated WordPress classes.

Valid: use of a current (non-deprecated) class. Invalid: use of a deprecated class.
$a = new WP_User_Query();
$a = new WP_User_Search(); // Deprecated WP 3.1.

WordPress.WP.DeprecatedFunctions | [ref]

Please refrain from using deprecated WordPress functions.

Valid: use of a current (non-deprecated) function. Invalid: use of a deprecated function.
$sites = get_sites();
$sites = wp_get_sites(); // Deprecated WP 4.6.

WordPress.WP.DeprecatedParameters | [ref]

Please refrain from passing deprecated WordPress function parameters. In case, you need to pass an optional parameter positioned after the deprecated parameter, only ever pass the default value.

Valid: not passing a deprecated parameter. Invalid: passing a deprecated parameter.
// First - and only - parameter deprecated.
get_the_author();
// First - and only - parameter deprecated.
get_the_author( $string );
Valid: passing default value for a deprecated parameter. Invalid: not passing the default value for a deprecated parameter.
// Third parameter deprecated in WP 2.3.0.
add_option( 'option_name', 123, '', 'yes' );
// Third parameter deprecated in WP 2.3.0.
add_option( 'my_name', 123, 'oops', 'yes' );

WordPress.WP.DeprecatedParameterValues | [ref]

Please refrain from using deprecated WordPress function parameter values.

Valid: passing a valid function parameter value. Invalid: passing a deprecated function parameter value.
bloginfo( 'url' );
bloginfo ( 'home' ); // Deprecated WP 2.2.0.

WordPress.WP.DiscouragedConstants | [ref]


WordPress.WP.DiscouragedFunctions | [ref]


WordPress.WP.EnqueuedResourceParameters | [ref]

The resource version must be set, to prevent the browser from using an outdated, cached version after the resource has been updated.

Valid: Resource has a version number. Invalid: Resource has no version number set.
wp_register_style(
    'someStyle-css',
    $path_to_local_file,
    array(),
    '1.0.0'
);
wp_register_style(
    'someStyle-css',
    $path_to_local_file,
    array()
);
Valid: Resource has a version number. Invalid: Resource has version set to false.
wp_enqueue_script(
    'someScript-js',
    $path_to_local_file,
    array( 'jquery' ),
    '1.0.0',
    true
);
wp_enqueue_script(
    'someScript-js',
    $path_to_local_file,
    array( 'jquery' ),
    false,
    true
);
Loading scripts in the header blocks parsing of the page and has a negative impact on load times. However, loading in the footer may break compatibility when other scripts rely on the resource to be available at any time.
In that case, you can pass `false` to make it explicit that the script should be loaded in the header of the page.
Valid: The resource is specified to load in the footer. Invalid: The location to load this resource is not explicitly set.
wp_register_script(
    'someScript-js',
    $path_to_local_file,
    array( 'jquery' ),
    '1.0.0',
    true
);
wp_register_script(
    'someScript-js',
    $path_to_local_file,
    array( 'jquery' ),
    '1.0.0'
);

WordPress.WP.EnqueuedResources | [ref]

Scripts must be registered/enqueued via wp_enqueue_script().

Valid: Script registered and enqueued correctly. Invalid: Script is directly embedded in HTML.
wp_enqueue_script(
    'someScript-js',
    $path_to_file,
    array( 'jquery' ),
    '1.0.0',
    true
);
printf(
    '<script src="%s"></script>',
    esc_url( $path_to_file )
);
Valid: Stylesheet registered and enqueued correctly. Invalid: Stylesheet is directly embedded in HTML.
wp_enqueue_style(
    'style-name',
    $path_to_file,
    array(),
    '1.0.0'
);
printf(
    '<link rel="stylesheet" href="%s" />',
    esc_url( $path_to_file )
);

WordPress.WP.GlobalVariablesOverride | [ref]


WordPress.WP.I18n | [ref]


WordPress.WP.PostsPerPage | [ref]

Using "posts_per_page" or "numberposts" with the value set to an high number opens up the potential for making requests slow if the query ends up querying thousands of posts.

You should always fetch the lowest number possible that still gives you the number of results you find acceptable.

Valid: posts_per_page is not over limit (default 100). Invalid: posts_per_page is over limit (default 100).
$args = array(
    'posts_per_page' => -1,
);
$args = array(
    'posts_per_page' => 100,
);
$args = array(
    'posts_per_page' => '10',
);

$query_args['posts_per_page'] = 100;

_query_posts( 'nopaging=1&posts_per_page=50' );
$args = array(
    'posts_per_page' => 101,
);

$query_args['posts_per_page'] = 200;

_query_posts( 'nopaging=1&posts_per_page=999' );
Valid: numberposts is not over limit (default 100). Invalid: numberposts is over limit (default 100).
$args = array(
    'numberposts' => -1,
);
$args = array(
    'numberposts' => 100,
);
$args = array(
    'numberposts' => '10',
);

$query_args['numberposts'] = '-1';

_query_posts( 'numberposts=50' );
$args = array(
    'numberposts' => 101,
);

$query_args['numberposts'] = '200';

_query_posts( 'numberposts=999' );

avatar

Looking for a developer who
truly cares about your business?

My team and I provide expert consultations, top-notch coding, and comprehensive audits to elevate your success.

Feedback

How satisfied you are after reading this article?