Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Php Codesniffer Laravel Package

squizlabs/php_codesniffer

PHP_CodeSniffer tokenizes PHP files to detect coding standard violations and automatically fix them. It ships two scripts: phpcs for sniffing and phpcbf for auto-correction, keeping code clean and consistent across teams and CI. The official continuation of the Squizlabs package.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Install as a dev dependency (never production).

composer require --dev squizlabs/php_codesniffer:^4.0

On older projects pinned to PHP 7.x/early 8.x, ^3.13 is the safer line; the 4.x major changed default behaviour and some sniff messages.

2. Run it once, on a narrow path, before writing any config.

./vendor/bin/phpcs app/Http/Controllers --standard=PSR12 -s

-s prints the sniff source code (e.g. PSR12.Files.FileHeader.SpacingAfterBlock) — this is the single most useful flag, because that string is what you paste into phpcs:ignore annotations and <exclude name="..."> rules.

3. Where to look first. The README is thin; the real documentation is the GitHub wiki: Usage, Advanced Usage (default configuration file), Configuration Options, and Annotated Ruleset. Read Annotated Ruleset before writing your own phpcs.xml.dist, not after.

4. First use case: a project ruleset file. Drop this at the repo root as phpcs.xml.dist and both phpcs and phpcbf pick it up automatically with no arguments:

<?xml version="1.0"?>
<ruleset name="App">
    <description>Project coding standard.</description>

    <file>app</file>
    <file>config</file>
    <file>database</file>
    <file>routes</file>
    <file>tests</file>

    <exclude-pattern>*/vendor/*</exclude-pattern>
    <exclude-pattern>*/node_modules/*</exclude-pattern>
    <exclude-pattern>*/storage/*</exclude-pattern>
    <exclude-pattern>*/bootstrap/cache/*</exclude-pattern>

    <arg name="extensions" value="php"/>
    <arg name="colors"/>
    <arg name="parallel" value="8"/>
    <arg name="cache" value=".phpcs.cache"/>
    <arg value="ps"/>

    <rule ref="PSR12"/>
    <rule ref="Generic.Files.LineLength">
        <properties>
            <property name="lineLimit" value="120"/>
            <property name="absoluteLineLimit" value="0"/>
        </properties>
    </rule>
</ruleset>

Then ./vendor/bin/phpcs and ./vendor/bin/phpcbf are your two everyday commands.

Implementation Patterns

Composer scripts as the team interface. Nobody should have to remember flags:

"scripts": {
    "lint": "phpcs",
    "lint:fix": "phpcbf",
    "lint:ci": "phpcs -q --report=checkstyle --report-file=build/phpcs.xml"
}

The fix-then-verify loop. phpcbf runs a limited number of fixer passes, and some sniffs only become fixable after another sniff has fixed the spacing around them. The reliable workflow is:

./vendor/bin/phpcbf app/Http/Controllers/FooController.php
./vendor/bin/phpcbf app/Http/Controllers/FooController.php   # second pass catches leftovers
./vendor/bin/phpcs  app/Http/Controllers/FooController.php   # confirm clean
git diff                                                      # ALWAYS eyeball the diff

Commit (or stash) before running phpcbf on a large tree — the fixer is powerful and occasionally wrong on unusual syntax.

CI gate. Use an explicit path rather than . so vendor/ never gets scanned:

- run: composer install --prefer-dist --no-progress
- run: ./vendor/bin/phpcs --report=checkstyle --report-file=checkstyle.xml

Exit codes matter: 0 clean, 1 violations found, 2 fixer failed, 3 processing/parse error. Treat 3 as a hard failure — it usually means an unparseable file or a tokenizer problem, not a style issue.

Pre-commit hook. Scope it to staged files only, or developers will disable it:

git diff --cached --name-only --diff-filter=ACM -- '*.php' \
  | xargs -r ./vendor/bin/phpcs --standard=phpcs.xml.dist

GrumPHP, CaptainHook, or a Husky lint-staged entry all wrap this fine.

Baseline for legacy codebases. Instead of <exclude-pattern>-ing half the app, freeze existing debt:

./vendor/bin/phpcs --generate-baseline     # writes phpcs-baseline.xml
./vendor/bin/phpcs --baseline=phpcs-baseline.xml

New violations fail CI; old ones are ignored until touched. Commit the baseline file and shrink it over time rather than regenerating it.

Enforce Laravel-specific conventions with built-in sniffs. You can get most of the way without writing a custom sniff:

<!-- no debug helpers in committed code -->
<rule ref="Generic.PHP.ForbiddenFunctions">
    <properties>
        <property name="forbiddenFunctions" type="array">
            <element key="dd" value="null"/>
            <element key="dump" value="null"/>
            <element key="var_dump" value="null"/>
            <element key="ray" value="null"/>
        </property>
    </properties>
</rule>

<!-- env() only belongs in config/ -->
<rule ref="Generic.PHP.ForbiddenFunctions">
    <properties>
        <property name="forbiddenFunctions" type="array">
            <element key="env" value="null"/>
        </property>
    </properties>
    <exclude-pattern>config/*</exclude-pattern>
</rule>

Custom sniffs for house rules. When a rule can't be expressed declaratively (e.g. "controllers must not exceed 300 lines", "no DB::raw() with an interpolated variable"), write a sniff. The pattern is always the same: extend PHP_CodeSniffer\Sniffs\Sniff, implement register() returning token constants, and process() emitting $phpcsFile->addError() / addWarning() / addFixableError(). Register it in the ruleset with <rule ref="AppStandard.Laravel.NoDbRaw"/> and point installed_paths at the directory containing AppStandard/:

./vendor/bin/phpcs --config-set installed_paths /path/to/your/standards

If you distribute standards via Composer, install phpcsstandards/composer-installer (the maintained successor to dealerdirect/phpcodesniffer-composer-installer) so installed_paths is wired up automatically.

Reports tailored to the audience. --report=summary for a quick file-level overview, --report=source to see which sniff is causing most of the noise (useful when deciding what to exclude), --report=diff to preview what phpcbf would change without touching files, --report=json for scripting.

Complement, don't replace, static analysis. PHPCS is token-level style and convention enforcement. It will not tell you a method returns the wrong type or that a query is N+1. Pair it with Larastan/PHPStan; they overlap almost not at all.

Gotchas and Tips

  • PHPCS does not ignore vendor/ for you. Running phpcs . from the project root will crawl vendor/, node_modules/, and storage/. Always declare <file> entries explicitly or add <exclude-pattern> rules. This is the number-one cause of "PHPCS is so slow".
  • Default standard changed. README documents PSR12 as the default, but on the 3.x line the implicit default was PEAR. If behaviour differs between machines, someone has a different major installed — always pin --standard or ship a ruleset.
  • phpcs.xml beats phpcs.xml.dist. The .dist file is the committed one; a developer's local phpcs.xml overrides it silently. Add phpcs.xml and .phpcs.cache to .gitignore and tell the team why.
  • Paths in a ruleset are relative to the ruleset file, not the CWD. --standard=/absolute/path/phpcs.xml.dist from a different directory still resolves <file> correctly, which is what you want in CI.
  • Blade templates produce garbage. .blade.php files are mostly inline HTML to the tokenizer; you'll get noise from Generic.Files.LineLength and little else of value. Exclude resources/views and lint the compiled/cached output only if you must.
  • phpcs:ignore placement is strict. It applies to the next line, or to the same line if written at the end of it. // phpcs:ignore Sniff.Name above a multi-line statement only suppresses the first line's errors. Prefer phpcs:disable/phpcs:enable for blocks, and always include the sniff name — bare ignores rot.
  • Don't run Pint and PHPCBF in the same pipeline. Pint wraps PHP-CS-Fixer; PHP-CS-Fixer and PHPCBF have different opinions about imports, blank lines, and braces. Pick one as the authority. If your team already uses Pint, use PHPCS only for additional checks (forbidden functions, custom sniffs) and exclude the sniffs Pint already owns, or drop one of the tools entirely.
  • Fixer conflicts are real. When two sniffs disagree, phpcbf may oscillate or emit a "fixer conflict" notice and stop touching the loop. Fix by excluding one sniff for that path (<exclude name="..."/> inside an <exclude-pattern> block) rather than fighting it.
  • Memory and parallel limits. --parallel speeds up big trees but scrambles report ordering and can break custom sniffs with static state. On large repos also set php -d memory_limit=512M vendor/bin/phpcs.
  • The cache can lie. .phpcs.cache keys off file mtime/size; stale results after a git checkout or branch switch are not unheard of. --no-cache when debugging a phantom violation.
  • Generic.Files.LineLength defaults (80/100) are far stricter than Laravel's ~120. Set lineLimit to 120 and absoluteLineLimit to 0 to disable the hard cap, or you'll get a wall of errors on day one and the team will tune the tool out.
  • Sniff messages and fixes are not stable across PATCH releases — the versioning section of the README says so explicitly. Don't write tests that assert on exact error message strings from third-party standards; assert on sniff codes and counts.
  • Extension points worth knowing: --runtime-set key value for one-off property overrides without editing the ruleset, <config name="..." value="..."/> for global settings, <rule ref="..."><exclude name="Sniff.Code"/></rule> for surgical disabling, and phpcs -e to list every installed sniff and phpcs -i to list installed standards — the fastest way to confirm a custom standard is actually registered.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route