php-collective/code-sniffer
PHP_CodeSniffer ruleset from PhpCollective. PSR-2 compliant with many extra sniffs/fixers (incl. PSR-12) plus an optional stricter standard (PhpCollectiveStrict). Install via Composer and run phpcs/phpcbf, or wire into CI/IDE.
Installation:
composer require --dev php-collective/code-sniffer
Configure phpcs.xml in your project root:
<?xml version="1.0"?>
<ruleset name="your-project">
<file>src/</file>
<file>tests/</file>
<rule ref="vendor/php-collective/code-sniffer/PhpCollective/ruleset.xml"/>
</ruleset>
First Use Case: Run a quick check on your codebase:
composer cs-check
(Add this to your composer.json scripts section as shown in the docs.)
Pre-Commit Hooks:
Integrate with tools like husky or pre-commit to run phpcs automatically:
# .pre-commit-config.yaml
- repo: local
hooks:
- id: phpcs
name: PHP Code Sniffer
entry: vendor/bin/phpcs
language: system
types: [php]
args: ["--standard=PhpCollective"]
CI/CD Integration: Add to your CI pipeline (e.g., GitHub Actions):
- name: Run PHP Code Sniffer
run: vendor/bin/phpcs --standard=PhpCollective
IDE Integration:
Configure PHPStorm or VSCode to run phpcs on save via file watchers or hotkeys (as documented).
Team Onboarding:
phpcs.xml rules in your CONTRIBUTING.md.PhpCollectiveStrict for new projects to enforce stricter standards early.Custom Rulesets: Extend the base ruleset for project-specific needs:
<ruleset name="ProjectRules">
<rule ref="vendor/php-collective/code-sniffer/PhpCollective/ruleset.xml">
<exclude name="PhpCollective.NamingConventions.ValidClassName.NotCamelCaps"/>
</rule>
<rule ref="Custom/Sniffs/ruleset.xml"/>
</ruleset>
Dynamic Configuration:
Use environment variables to toggle rules (e.g., disable DisallowFunctions in CI):
PHPCS_SKIP_DISALLOW_FUNCTIONS=1 vendor/bin/phpcs
Fixers Workflow:
composer cs-fix for auto-fixable issues.git diff before committing.Partial Fixes: Fix specific files interactively:
vendor/bin/phpcbf --interactive src/MyClass.php
False Positives:
vendor/bin/tokenize to debug complex sniffs (e.g., nested closures).<exclude name="vendor/legacy-library/"/>
Performance:
node_modules, storage/logs) from phpcs.xml:
<exclude-pattern>.*/(node_modules|storage/logs)/.*</exclude-pattern>
Strict Mode:
DeclareStrictTypesAfterFileDoc may break type coercion in older PHP versions. Test thoroughly.PHP Version Safety:
DisallowFunctions (e.g., phpVersion="8.2" in PHP 8.1) will flag core functions. Use 'off' to disable:
<rule ref="PhpCollective.Internal.DisallowFunctions">
<properties>
<property name="phpVersion" value="off"/>
</properties>
</rule>
Verbose Output:
Run with -v to see detailed errors:
vendor/bin/phpcs -v src/
Sniff-Specific Debugging:
Use --report=full to see token-level details for a specific rule:
vendor/bin/phpcs --report=full --standard=PhpCollective src/MyClass.php
Testing Sniffs:
php tests/generate.php MyNamespace.MySniff
composer test
IDE Debugging:
phpcs/phpcbf commands.Custom Sniffs:
Sniffs/ with matching test files in tests/.Sniffs/
└── MyCompany/
└── Sniffs/
└── Arrays/
└── DisallowEmptyArraysSniff.php
tests/
└── MyCompany/
└── Sniffs/
└── Arrays/
└── DisallowEmptyArraysSniffTest.php
Overriding Rules:
phpcs.xml:
<rule ref="PhpCollective.Commenting.DocBlockReturnVoid">
<properties>
<property name="checkReturnTypeHint" value="false"/>
</properties>
</rule>
Composite Rulesets:
Combine multiple standards (e.g., PhpCollective + SlevomatCodingStandard):
<ruleset name="Composite">
<rule ref="vendor/php-collective/code-sniffer/PhpCollective/ruleset.xml"/>
<rule ref="vendor/slevomat/coding-standard/SlevomatSniffs/ruleset.xml"/>
</ruleset>
Parallel Execution:
Speed up large codebases with --parallel (PHP 7.4+):
vendor/bin/phpcs --parallel=8
Incremental Adoption:
PhpCollective and migrate to PhpCollectiveStrict over time.severity="0" to silence rules temporarily:
<rule ref="PhpCollective.ControlStructures.DisallowShortTernary">
<severity>0</severity>
</rule>
Automated Fixes:
phpcbf with git add in a pre-commit hook:
vendor/bin/phpcbf --standard=PhpCollective --diff && git add -u
Documentation:
sniffs.md after adding new sniffs:
composer docs
Legacy Code Handling:
exclude-pattern to skip legacy directories:
<exclude-pattern>.*/legacy/.*</exclude-pattern>
How can I help you explore Laravel packages today?