zebra-north/phpcs-short-types
A PHP_CodeSniffer ruleset that enforces short, consistent type declarations in PHP code. It flags long or legacy type names and helps keep type hints and annotations concise across your codebase, with easy integration into existing PHPCS setups and CI pipelines.
Architecture fit. The package's shape changed materially in v1.1.0. Previously it was a single self-contained sniff — one class implementing PHP_CodeSniffer\Sniffs\Sniff, registered by a ruleset ref, with no coupling to application code and no runtime footprint. The release notes ("CodeSniffer v4 has changed internally so the previous hack no longer works. The only way now is to replace the faulty sniffs with modified versions") indicate the package now ships patched copies of upstream sniffs and depends on class-resolution ordering to shadow the originals. That moves it from "one small rule" to "a partial, vendored fork of third-party tokenizer-dependent code loaded into the same process as every other standard." The runtime footprint is still zero and the integration surface is still a dev dependency plus a rule ref, but the blast radius is no longer confined to one diagnostic: if the shadowing mechanism overrides a shared sniff, the package can change behavior of rules the team never intended to touch. Verdict: still acceptable for a lint lane, but it is now a change that deserves a reviewable diff and a rollback commit, not a fire-and-forget composer require.
Integration feasibility. Still high, with a new gating condition: PHPCS major version determines which package version you may use, and the two cannot be chosen independently. v1.1.0 is the PHPCS 4.x path; older tags are the 3.x path. Teams on PHPCS 3.x gain nothing from upgrading and should stay pinned; teams planning the 4.x migration should treat this package as a dependency of that migration, not as an independent tooling improvement. Installation mechanics are unchanged (composer require --dev, ruleset ref, config.allow-plugins for the Dealerdirect installer), but the ref string and the load mechanism now matter more: a custom standard that replaces sniffs typically requires installed_paths ordering or a standard that re-registers overridden sniffs, and getting that wrong produces the silent-no-op failure mode below.
Technical risk. Moved from low to low-to-moderate, and the risk profile is different in kind:
installed_paths order, standard inclusion order, or autoload precedence. That is environment-sensitive: a developer machine and CI can resolve differently, and an upstream fix shipping in a future PHPCS or Slevomat release may be silently masked by the vendored copy. This is the most important thing to verify — confirm exactly which sniffs are replaced and whether the replacement is additive or exclusionary.int|boolean, ?integer, array<integer>, positive-int), and whether addFixableError is implemented so phpcbf can remediate.Key questions. Several earlier questions are now answered or superseded; the list is:
installed_paths manipulation, or (c) autoload classmap precedence? Only (a) is predictable enough for a shared CI pipeline.Stack fit. Unchanged at the top level — good fit for a Laravel team already running PHPCS, still not honored by Laravel Pint (which uses its own fixed ruleset and ignores phpcs.xml). The Pint-versus-PHPCS lane decision must be settled first, as before. The new wrinkle is that adopting this package on PHPCS 4.x means adopting a specific resolution order for sniffs, which is a toolchain-level decision, not a per-project one. If several Laravel services share a base ruleset, validate the ordering once in that shared ruleset rather than per repo.
Migration path. Additive and reversible in principle, but the v1.1.0 step is no longer a one-line config change:
composer require --dev zebra-north/phpcs-short-types:^1.1 with the installer plugin allowed, and pin PHPCS explicitly in composer.json rather than floating it.phpcs.xml.dist, scoped with <file> to app/, src/, tests/ and <exclude-pattern> for vendor/, generated code, and cached views.phpcs --report=summary) plus phpcs -e to confirm the effective sniff list — the sniff inventory is now the thing to check, not just the message count.@param boolean and a prose sentence ("returns a boolean indicating…") and assert the expected results, so a future resolution-order change cannot silently disable the rule.phpcbf on a branch, review the docblock diff by hand, land as one mechanical commit in .git-blame-ignore-revs. Promote to blocking CI only after baseline is clean.Compatibility. Two axes now instead of one. First, PHPCS 4.x vs 3.x — the package is effectively version-locked to the major. Second, coexistence with the standards it patches: if the team also runs Slevomat or PSR-12 and this package ships modified copies of overlapping sniffs, confirm no duplicate diagnostics and no lost upstream behavior. Also re-check minimum PHP version against your matrix, since PHPCS 4.x raised its floor.
Sequencing. (1) Inventory PHPCS versions across repos. (2) Review the vendored sniff diff and confirm the override mechanism. (3) Decide Pint-vs-PHPCS lane. (4) Land config plus fixture plus non-blocking CI job. (5) Flip to blocking. Effort is still hours per repo for the wiring, plus a half-day of upfront review of the sniff replacements — the added cost is entirely in step 2, and it is not optional.
Maintenance. This was already the weak point; v1.1.0 makes it structurally weaker. The package is no longer "one small class you could fork in an afternoon" — it now carries modified third-party sniffs whose correctness must be re-validated on each PHPCS and Slevomat release. Treat it as vendored code that happens to arrive via Composer: pin an exact version, commit composer.lock, and write down the escape hatch. The fork plan still exists but is now larger: it means owning a patched sniff set, not one rule. Budget it as the likely long-term outcome, and assign it a named owner.
Support. Still no vendor SLA and no expectation of issue response. The difference is that a support failure now blocks the PHPCS 4.x migration rather than one lint rule, because the package has positioned itself as the workaround for a platform-level change. Add a runbook entry specifically for "PHPCS bumped and this package has not caught up" — the answer is to drop the rule temporarily, not to hold the whole toolchain back.
Scaling. Negligible on compute. Comment-token scanning is noise beside the rest of the suite, it scales linearly with file count exactly as PHPCS already does, and it never ships to production. The scaling concern is organizational: one more piece of shadowed behavior in a shared standard means every repo inheriting that standard inherits the resolution-order semantics, so a mistake propagates fleet-wide rather than to one project.
Failure modes.
installed_paths lets CI go green enforcing nothing. Guarded by the failing fixture above; more necessary now than before.phpcs -e in CI.phpcbf rewriting docblocks can corrupt annotations PHPStan/Psalm then reject. Review the diff; never auto-merge.Ramp-up. Still essentially zero for developers — it is a lint message with an obvious remediation and short-form scalar names already dominate modern PHP. The ramp-up cost has shifted to the toolchain owner: whoever maintains CI now has to understand the override mechanism, keep PHPCS pinned, and re-review the vendored sniffs each upgrade cycle. That is a new, if small, standing obligation that did not exist at the prior assessment.
Bottom line. v1.1.0 is a genuine but expensive fix: it restores PHPCS 4.x compatibility at the cost of turning a one-class rule into a maintained fork of upstream sniffs with order-dependent loading. The prior conclusion — adopt because the cost is near zero — no longer holds cleanly. Adopt only if PHPCS 4.x support is on your roadmap, and only after reviewing exactly which sniffs are replaced; otherwise stay on the older tag with PHPCS 3.x and revisit at the next major. The opportunity score nudges from ~47 to ~50: capability is unchanged and the narrow rule still has modest upside, but the maintenance obligation per unit of value went up.
How can I help you explore Laravel packages today?