zicht/standards-php
Zicht's shared PHP coding standards package bundles PHP_CodeSniffer rules and static analysis configuration for consistent code style across projects. Install it with Composer and reference the ruleset in your phpcs.xml to enforce quality checks.
Install it as a dev dependency — it is a coding standard, not runtime code:
composer require --dev zicht/standards-php
This pulls in squizlabs/php_codesniffer and registers a ruleset. Before writing any config, look at two things:
vendor/zicht/standards-php/ruleset.xml — this tells you the registered standard name (conventionally Zicht) and exactly which sniffs are enabled, excluded, or configured (line length, namespace rules, unused imports, etc.).vendor/bin/phpcs -i — confirms the standard is visible to PHPCS from your project.Then create phpcs.xml.dist at the project root so everyone (and CI) uses the same rules:
<?xml version="1.0"?>
<ruleset name="Project">
<description>Project coding standard</description>
<file>src</file>
<file>tests</file>
<arg name="extensions" value="php"/>
<arg name="colors"/>
<arg value="sp"/> <!-- show sniff codes, progress -->
<rule ref="Zicht"/>
</ruleset>
First use case: run it on a single directory to see the damage before committing to a full sweep.
vendor/bin/phpcs src/Http/Controllers
vendor/bin/phpcbf src/Http/Controllers # auto-fix what can be fixed
Start with phpcbf on new code and a narrow scope, then widen.
Wire it into Composer scripts so it is one command everyone remembers:
"scripts": {
"lint": "phpcs",
"lint:fix": "phpcbf",
"lint:changed": "phpcs --report=summary"
}
CI: fail the build, but keep the signal clean. Run phpcs as its own job (or step) separate from tests, with --report=full and --no-colors for readable logs. Use --cache=vendor/.phpcs-cache to make repeated runs fast.
Incremental adoption on an existing codebase. Do not try to fix everything on day one. Pick one of:
<file> to new modules only and expand over time.<exclude-pattern>src/Legacy/*</exclude-pattern>.phpcbf per-directory and commit the mechanical fixes as separate "style only" PRs so review noise stays out of feature PRs.<severity> or per-sniff <exclude name="..."> to defer the sniffs that need judgement (docblocks, complexity, line length) while enforcing whitespace/imports immediately.Different rules for different paths. Test files usually should not be held to the same docblock or line-length rules:
<rule ref="Zicht">
<exclude name="Zicht.Something.TooStrict"/>
</rule>
<rule ref="Zicht">
<exclude-pattern>tests/*</exclude-pattern>
</rule>
(Confirm the sniff codes from the ruleset.xml rather than guessing them.)
Editor integration. Point PhpStorm / VS Code PHPCS extensions at vendor/bin/phpcs and the project phpcs.xml.dist, not a globally installed PHPCS — otherwise editors and CI disagree and you get "works in my IDE" churn.
Pre-commit gate. Pair with CaptainHook or a Husky/GrumPHP task that runs phpcs on staged files only. This is where the standard earns its keep day-to-day — catching drift before it reaches a PR.
Layering with other standards. Add it before or after more specific standards in the same ruleset; later <rule> blocks can override or exclude. Keep the ordering deliberate and documented in a comment, because "which standard wins" is a common source of confusion in reviews.
--standard=Zicht only works if PHPCS finds the installed paths. If you get "standard not found", pass the ruleset path directly: --standard=vendor/zicht/standards-php/ruleset.xml, and/or set <config name="installed_paths" value="vendor/zicht/standards-php"/> via vendor/bin/phpcs --config-set installed_paths ....zicht/standards-php is require-dev; treat minor bumps as potentially build-breaking. Lock it in composer.lock, and review the changelog when updating — new sniffs appear without warning and turn green CI red across unrelated PRs.phpcbf means the standard passes; always re-run phpcs after fixing.--warning-severity=0 or <config name="ignore_warnings_on_exit" value="1"/> to keep CI meaningful — but be honest that you're suppressing signal.phpcs at a different version will report different sniff results. Always invoke vendor/bin/phpcs in CI, scripts, and hooks.vendor/. Otherwise you will "fix" code you don't own.--cache is great until you change phpcs.xml.dist and results look wrong; delete vendor/.phpcs-cache when debugging odd diffs.phpcbf rewrites files; a pre-commit hook must git add the modified files back or you'll commit unformatted code and be confused by the next run.phpcs.xml.dist with <exclude> for individual sniffs, <severity> overrides, and <properties> on specific sniffs. Only fork if you need to change a sniff's internal configuration in a way the ruleset doesn't expose — and then track upstream changes, since there are no dependents to lean on for community fixes.How can I help you explore Laravel packages today?