php-collective/code-sniffer
PhpCollective Code Sniffer Standards
0.6.8
403K downloads/mo
#4101 most downloaded on Packagist
php-collective/code-sniffer
What this package is like to depend on
Last release 17 days ago
06 Aug 2026
Ships fairly regularly
a new release about every 4 weeks
Rarely documented
notes for 10 of 47 stable releases
Nothing withdrawn
no release was ever pulled
3 years old
47 releases · first in 2023
22 releases in the last 12 months
see the full history below
Release timeline
47 releases · Oct 2023 to Aug 2026Releases
latest 47-
0.6.806 Aug 2026Release notes
Open source →Improvements
-
Return by reference is covered too (#83). The reference marker added in 0.6.7 required a variable or a variadic ellipsis on the right, so
function & getItems()slipped through - the thing on the right is a function name. That form is now matched on the precedingfunction, closure orfnkeyword instead.With this,
PhpCollective.WhiteSpace.ImplicitCastSpacingcovers every constructpsr2r-sniffer'sUnaryOperatorSpacingdid, and one it did not (! $b), so the downstream sniff can be retired.
Full Changelog: 0.6.7...0.6.8
-
-
0.6.706 Aug 2026Release notes
Open source →Improvements
-
The reference operator is now covered by
PhpCollective.WhiteSpace.ImplicitCastSpacing(#82). That sniff already owned this shape for!,@and unary minus, so& $listjoins it rather than arriving as a separate sniff.$bad = & $list; // reported foreach ($items as & $item) {} // reported foreach ($items as $k => & $v) {} // reported function f(array & $items) {} // reported function g(& ...$args) {} // reported $ok = &$list; // untouched $okBitwise = $a & $b; // untouched function h(int $x = self::A & self::B) {} // untouched
Telling a reference from a bitwise and takes more than the preceding token, since a type hint precedes the marker in
function f(array & $items)and reads exactly like a left operand. A reference is one that stands in front of a variable, or the ellipsis of a by-reference variadic, and either follows something that cannot end a value or sits in a parameter list.Full Changelog: 0.6.6...0.6.7
-
-
0.6.606 Aug 2026Release notes
Open source →Fixes
- Calls at the very start of a file were skipped (#80, #81). Five sniffs guarded with
if (!$previous)on afindPrevious()result, and index0- the open tag - is falsy. So<?php sizeof($x);and<?php is_null($x);were silently ignored while the same call one line lower was caught. AffectedRemoveFunctionAlias,NoIsNull,DisallowFunctions(both copies) andShortCast.
Improvements
-
Duplicate reporting removed (#80). Three constructs were each flagged by two or three rules at once. In every case the rule with the widest coverage stays and the narrower ones are silenced, so nothing stops being detected - it is reported once instead of two or three times.
Construct Kept Silenced long casts SlevomatCodingStandard.PHP.TypeCastPSR12.Keywords.ShortFormTypeKeywords,PhpCollective.PHP.ShortCast.LongInvalidincrementer spacing Generic.WhiteSpace.IncrementDecrementSpacingImplicitCastSpacing.WhitespaceBeforeVariable/.WhitespaceAfterVariablesizeof()PhpCollective.PHP.RemoveFunctionAliasthe sizeofentry onGeneric.PHP.ForbiddenFunctionsCoverage went up rather than down:
(double)casts were previously reported by only one of the three cast rules, and that is the one that stayed. -
Unary minus spacing is now checked (#80).
- $ahad no coverage.PhpCollective.WhiteSpace.ImplicitCastSpacingalready owned this shape for!and@, so it gainedT_MINUS. Detection is deliberately conservative - a minus counts as unary only when the preceding token cannot end a value, so subtraction such as__LINE__ - 1is left alone.- -$ikeeps its space, since closing it would produce a decrement.
Full Changelog: 0.6.5...0.6.6
- Calls at the very start of a file were skipped (#80, #81). Five sniffs guarded with
-
0.6.506 Aug 2026Release notes
Open source →Fixes
-
Security: raise the
squizlabs/php_codesnifferfloor to^4.0.2(#75). CVE-2026-67434, an OS command injection advisory published 2026-08-05, covers>=4.0.0,<4.0.2. The previous^4.0.1constraint allowed an affected version. -
Generic.PHP.DeprecatedFunctionswas effectively disabled (#71). The ruleset set the sniff'sforbiddenFunctionsproperty, which replaces the list the sniff builds in its constructor from the Reflection API. The standard reported fewer deprecations than plainGenericdid -utf8_encode()among them. Removed functions such ascreate_function()andeach()moved toGeneric.PHP.ForbiddenFunctions, where a property override is safe. -
VoidCastandPipeOperatorSpacingmatched nothing on PHP 8.5 (#71). Both sniffs target PHP 8.5 syntax, and PHP 8.5 collapses each construct into a single token -T_VOID_CASTandT_PIPE. The sniffs registered only the pre-8.5 multi-token shapes, so on the version that introduced the syntax they silently passed everything. PHP 8.5 also joined the CI matrix. -
ConsistentIndentmis-indented PHP 8.4 property hooks (#76). Property hook braces are not modeled as scopes by PHP_CodeSniffer, so a hook block read as a single indent level and phpcbf dedented the second hook while leaving its body and braces in place. -
Attribute names are no longer rewritten as function calls (#78). An attribute name sits in front of a parenthesis just like a call, so an attribute sharing a name with a function alias was reported and auto-fixed -
#[Pos(1)]became#[current(1)], which does not compile. -
DocCommentemitted tab indentation (#79). Two fixes built indentation asstr_repeat("\t", column - 1), so phpcbf wrote tabs that the standard's ownGeneric.WhiteSpace.DisallowTabIndentthen reports, and used a column offset as a repeat count - four spaces of indent produced four tabs. -
DocBlockTagGroupingreported a fix it never applied (#74).NoExtraNewlineBeforeTagswas listed as fixable, but an inverted guard meant phpcbf skipped the change every time.
Improvements
-
RemoveFunctionAliascovers more aliases (#70). Addeddoublevaltofloatval, alongsidepos,show_sourceanduser_error. The unreachabledieandprintentries are gone;dieis handled by the Exit sniff. -
Fully-qualified global function calls are now detected (#72). Five sniffs -
RemoveFunctionAlias,NoIsNull,PreferCastOverFunction,DisallowFunctionsandPhpSapiConstant- matched only bareT_STRINGnames, so a leading-backslash call was invisible to all of them. Namespaced calls such asFoo\pos()remain untouched, and fixers that replace the name preserve the backslash.
Full Changelog: 0.6.4...0.6.5
-
-
0.6.406 Jun 2026Release notes
Open source →Fixes
DocBlockVarfixer no longer corrupts callable/Closureproperty types when appending a missingnull. The first-space split used to cut a\Closure(string): stringsignature in half, producing an unparseable@varannotation. Types with internal structure (callable/Closuresignatures, generics, array shapes) are now left untouched, while simple types with a trailing parenthetical description still get their missingnullappended.
Full Changelog: 0.6.3...0.6.4
-
0.6.328 May 2026Release notes
Open source →Fixes
- Proper native union type order - also consistent with docblocks - #67
- Fix phpcbf conflict on anonymous class bodies in ConsistentIndent - #68
Full Changelog: 0.6.2...0.6.3
-
0.6.213 May 2026Release notes
Open source →Improvements
- Cache class name resolution and skip redundant return-type body scans (#62)
- O(1)
conditionschecks + cached arrow-function scopes inConsistentIndentSniff(#63) - Cache
UseStatementsTrait::getUseStatementsand bound the throw class-name lookup to the current statement (#64) - Cache docblock FQCN lookups (
parseUseStatements/getNamespace) and dedupe per-doc-block processing (#65) - Cache
UseStatementSniff::getUseStatementsacross phpcbf fix iterations (#66)
Combined, these cut
composer cs-checkwall-clock time roughly in half on large method-heavy codebases. On an 11k-line CakePHP controller the slowest single file went from ~40s to ~6s; on a 1095-file project the whole-codebase scan dropped from ~2m08s to ~30s withparallel=16.Full Changelog: 0.6.1...0.6.2
-
0.6.112 May 2026Release notes
Open source →Improvements
- Extend
DocBlockTagOrderto class, interface, and trait docblocks with a new configurableclassOrderproperty (#59) - Add opt-in inner-bucket ordering to
DocBlockTagOrdervia a newinnerOrderproperty and separateInnerOrderInvaliderror code, so inner ordering can be enabled and scoped independently of bucket ordering (#60)
Full Changelog: 0.6.0...0.6.1
- Extend
-
0.6.014 Apr 2026Release notes
Open source →Fixes
- Fix DocBlockParamAllowDefaultValueSniff positional mismatch on partial
@paramlists, which could cause an infinite fixer loop with DocBlockParamTypeMismatchSniff (#58)
Improvements
- Replace internal sniffs with their PHPCSExtra Universal equivalents (supersets):
PhpCollective.ControlStructures.DisallowAlternativeControlStructures→Universal.ControlStructures.DisallowAlternativeSyntax,PhpCollective.WhiteSpace.CommaSpacing→Universal.WhiteSpace.CommaSpacing(#55) - Add additional Universal sniffs to the ruleset (#54)
- Add Universal attribute and whitespace sniffs (#56)
- Disallow partial uses in
ReferenceUsedNamesOnly(#57)
Migration
Partial namespace references (e.g.
Mockery\MockInterfacewhen onlyMockeryis imported) are now flagged and must be imported via a fullusestatement. To keep the previous behavior, override the property in your project'sphpcs.xml:<rule ref="SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly"> <properties> <property name="allowPartialUses" value="true"/> </properties> </rule>
Full Changelog: 0.5.5...0.6.0
- Fix DocBlockParamAllowDefaultValueSniff positional mismatch on partial
-
0.5.510 Apr 2026Release notes
Open source →Fixes
- Fix docblock indentation loss when EmptyEnclosingLine sniff interacted with DisallowTabIndent (#52)
- Fix InlineDocBlockSniff for abstract/interface methods - skip methods without body (#51)
- Fix NoIsNullSniff calling wrong method for trailing comparisons (#49)
- Fix EnumCaseCasingSniff multibyte support with proper
mb_strtoupper()(#49)
Full Changelog: 0.5.4...0.5.5
-
0.5.427 Mar 2026Nothing published for this version
-
0.5.311 Feb 2026Nothing published for this version
-
0.5.201 Feb 2026Nothing published for this version
-
0.5.103 Dec 2025Nothing published for this version
-
0.5.027 Nov 2025Nothing published for this version
-
0.4.627 Oct 2025Nothing published for this version
-
0.4.523 Oct 2025Nothing published for this version
-
0.4.422 Oct 2025Nothing published for this version
-
0.4.322 Oct 2025Nothing published for this version
-
0.4.220 Oct 2025Nothing published for this version
-
0.4.120 Oct 2025Nothing published for this version
-
0.4.029 Sep 2025Nothing published for this version
-
0.3.119 Aug 2025Nothing published for this version
-
0.3.009 Aug 2025Nothing published for this version
-
0.2.2109 Aug 2025Nothing published for this version
-
0.2.2004 Aug 2025Nothing published for this version
-
0.2.1929 Jul 2025Nothing published for this version
-
0.2.1811 Jul 2025Nothing published for this version
-
0.2.1729 Jun 2025Nothing published for this version
-
0.2.1608 Jun 2025Nothing published for this version
-
0.2.1512 May 2025Nothing published for this version
-
0.2.1429 Mar 2025Nothing published for this version
-
0.2.1313 Mar 2025Nothing published for this version
-
0.2.1224 Feb 2025Nothing published for this version
-
0.2.1130 Nov 2024Nothing published for this version
-
0.2.1020 Nov 2024Nothing published for this version
-
0.2.916 Oct 2024Nothing published for this version
-
0.2.816 Oct 2024Nothing published for this version
-
0.2.705 Aug 2024Nothing published for this version
-
0.2.629 Mar 2024Nothing published for this version
-
0.2.529 Mar 2024Nothing published for this version
-
0.2.402 Jan 2024Nothing published for this version
-
0.2.302 Jan 2024Nothing published for this version
-
0.2.222 Nov 2023Nothing published for this version
-
0.2.124 Oct 2023Nothing published for this version
-
0.2.017 Oct 2023Nothing published for this version
-
0.1.007 Oct 2023Nothing published for this version