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

Coding Standard Laravel Package

libero/coding-standard

A shared coding standard for Libero PHP projects, bundling PHP_CodeSniffer rules and fixer configuration to keep Laravel codebases consistently formatted. Add it via Composer to align team style rules and CI lint checks across repositories.

View on GitHub
Deep Wiki
Context7

Getting Started

libero/coding-standard is a PHP_CodeSniffer (PHPCS) ruleset package, not a framework library. You install it as a dev dependency and let it drive phpcs / phpcbf against your Laravel codebase. The earlier "frozen 2019 snapshot" framing no longer holds: v0.5.0 shipped with eight new sniffs, so treat this as a low-traffic but maintained house style. It is still pre-1.0, so semver rules are loose — pin an exact version and expect opinionated additions between minor releases.

1. Install alongside a compatible PHPCS. The package's composer.json pins a PHPCS version from the 3.4/3.5 era. If your project already has a newer squizlabs/php_codesniffer, Composer will likely refuse the resolution. The cleanest way is still an isolated bin namespace:

composer require --dev bamarni/composer-bin-plugin
composer config extra.bin-namespace "tools"
composer bin tools require --dev libero/coding-standard:0.5.0
vendor/bin/tools/phpcs -i

Pin the exact tag (0.5.0, not ^0.5) — see Gotchas for why.

2. Register the standard. If dealerdirect/phpcodesniffer-composer-installer is present and the package declares type: phpcs-standard, it registers automatically. Otherwise point PHPCS at the directory containing the ruleset.xml:

vendor/bin/phpcs --config-set installed_paths vendor/libero/coding-standard
vendor/bin/phpcs -i          # should now list the standard by name

3. Look at the ruleset first. Open vendor/libero/coding-standard/ruleset.xml. The name attribute inside it (often something like Libero) is the identifier you pass to --standard= — it is not the Composer package name. Skim the <rule ref="..."> entries so you know whether it builds on PSR-2, PSR-12, or Symfony. Then note the v0.5.0 additions, because they are the ones that will generate the most diff on an existing codebase:

  • static closures when $this is unused (#51)
  • trailing comma in multi-line arrays (#53)
  • shorthand scalar/phpdoc types (#52)
  • no unnecessary semicolons (#55)
  • no useless final on methods in final classes (#54)
  • no late-static binding for constants or in final classes (#49)
  • arrays must be initialised before being appended to (#48)
  • revised ternary-expression rules (#50)

4. First use case. Audit a single directory, read-only, before touching anything:

vendor/bin/phpcs --standard=Libero --extensions=php --report=source app/

Prefer --report=source over --report=summary here: with the new sniffs you want to see which rules dominate the noise before committing to a fix bill. Only then decide whether to adopt, extend, or vendor a trimmed copy of the ruleset.

Implementation Patterns

Wrap it in a project ruleset. Never invoke the vendor standard directly in scripts — create phpcs.xml.dist at the project root that references it and layers Laravel-specific exclusions. This keeps command lines short and makes the exclusions reviewable:

<?xml version="1.0"?>
<ruleset name="Acme">
    <description>Acme Laravel code style</description>

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

    <rule ref="Libero"/>

    <exclude-pattern>*/vendor/*</exclude-pattern>
    <exclude-pattern>*/storage/*</exclude-pattern>
    <exclude-pattern>*/bootstrap/cache/*</exclude-pattern>
    <exclude-pattern>*/_ide_helper*.php</exclude-pattern>
    <exclude-pattern>*/database/migrations/*</exclude-pattern>
</ruleset>

Run it with no arguments once phpcs.xml.dist exists — PHPCS auto-discovers it.

Opt out of individual v0.5.0 sniffs by name, not by file. Several of the new rules are house opinions rather than universal consensus (notably #50 ternary form and #52 shorthand types). Disable them surgically so you keep the rest:

<rule ref="Libero">
    <exclude name="Libero.Classes.StaticClosure"/>
    <exclude name="Libero.Arrays.TrailingComma"/>
</rule>

Use the sniff codes the -s flag prints (phpcs -s --report=full app/) rather than guessing the code from the changelog text.

Composer scripts as the single entry point. Both developers and CI should call the same aliases, so nobody "fixes" style with a different flag set:

"scripts": {
    "lint": "phpcs",
    "lint:fix": "phpcbf || true",
    "lint:changed": "phpcs --report=full --filter=gitstaged"
}

The gitstaged filter is the pragmatic way to introduce a strict standard into a legacy app: check only what is about to be committed, so the codebase does not have to be clean on day one. It is also the cheapest way to absorb the new sniffs — they will only bite files you touch.

Incremental adoption via baseline. PHPCS has no native baseline, so either (a) generate a report once and grandfather the offending files with <exclude-pattern> entries, or (b) use --report=source to rank sniffs by frequency, fix the top three, and override the rest in your project ruleset. On a fresh v0.5.0 run expect #53 (trailing commas) and #51 (static closures) to dominate volume; both are mechanically fixable, so they are good candidates for a phpcbf-only commit.

Upgrade runbook. Because v0.5.0 is additive, upgrading is a deliberate one-off task rather than a routine bump:

rm -f .phpcs-cache
composer bin tools require --dev libero/coding-standard:0.5.0
vendor/bin/tools/phpcs --report=source > before.txt   # new violations, by sniff
composer lint:changed                                # gate only new/edited files

Diff before.txt against a pre-upgrade report to separate pre-existing debt from newly introduced rules, and land the standard bump as its own commit — never mixed with a feature branch.

CI integration. In GitHub Actions, pin PHPCS to the version the standard was built against and cache Composer, then run the project script:

- uses: shivammathur/setup-php@v2
  with:
    php-version: '7.4'
    tools: composer
- run: composer install --prefer-dist --no-progress
- run: composer lint

If you use the bamarni bin namespace, swap the tool install to composer bin tools install and call vendor/bin/tools/phpcs.

Editor parity. In PhpStorm, add the standard under Settings → PHP → Quality Tools → PHP_CodeSniffer by pointing at the PHPCS binary, then pick the standard by its ruleset name. This matters more than it looks: if the editor and CI disagree, developers will fix violations locally that CI still flags, which erodes trust in the standard fast.

Auto-fix workflow. phpcbf runs on a clean tree only. The idiomatic loop is branch → composer lint:fix → review the diff → composer lint to confirm zero remaining errors → commit. Anything phpcbf cannot fix (naming, complexity, unused variables) still needs the manual pass.

Gotchas and Tips

The static-closure sniff can break Laravel's $this binding. #51 flags any closure that does not textually reference $this, but Laravel binds $this into certain closures at call time — route group closures in Route::group(), macro definitions, and container bind/extend callbacks. Adding static to one of these compiles fine and fails at runtime with "Using $this when not in object context" — often only on a route or queue path your test suite does not exercise. Scope the sniff away from routes/, service providers, and macro registration, or exclude it outright and rely on code review.

Trailing-comma rule churns config arrays and bloats diffs. #53 will rewrite every multi-line array in config/ and database/. That is harmless but generates a large, unreviewable first commit, and every future array edit gains a line. Land it as a dedicated formatting commit, then add .git-blame-ignore-revs so git blame stays useful.

Pre-1.0 semver means minor bumps can break CI. v0.5.0 proves the package ships new sniffs on minor versions. composer require libero/coding-standard:^0.5 lets the next minor red a green build with no application change. Pin the exact version, and treat standard upgrades as scheduled work with the upgrade runbook above.

Shorthand-types sniff can fight your static analysis. #52 normalising @param integer → @param int is fine, but if it also rewrites nullable/union docblocks it can contradict what Larastan/PHPStan infers from PHP 8 native types. Run phpstan analyse immediately after the first phpcbf pass; if the two disagree, exclude the sniff for the affected paths rather than letting the fixer win.

"Arrays must be created before being used" targets a real but narrow pattern. #48 flags $bucket[] = $x with no prior declaration — common in aggregation loops in reports and exports. The fix is an explicit $bucket = [];, which is a genuine improvement, but it will also flag $data[$key][] = $v inside array-building helpers where the key is intentionally created on demand. Read those before auto-fixing.

The dependency ceiling is still the real blocker. A ruleset that grew from a 2019-era PHPCS pin can still conflict with a modern squizlabs/php_codesniffer, and on a PHP 8.x Laravel app this typically manifests as a Composer conflict, missing Generic.PHP.* sniffs, or fatal errors when PHPCS loads the ruleset. Isolating PHPCS in bamarni/composer-bin-plugin remains the only clean fix short of forking.

installed_paths is machine-global, not project-local. phpcs --config-set writes to a config file outside the repo. Your laptop will pass and CI will fail with "Referenced sniff … does not exist". Either commit the dealerdirect plugin to composer.json or re-set installed_paths as an explicit CI step. Never rely on a developer's local --config-set.

Relative sniff paths break when the ruleset moves. Custom sniffs inside a standard are usually declared as <rule ref="./Libero/Sniffs/...">, resolved relative to the ruleset.xml. If you copy the ruleset into your project root to customize it, those paths silently resolve to nothing and you lose the custom checks. Either <rule ref="Libero"/> wholesale, or <rule ref="vendor/libero/coding-standard/Libero/Sniffs/..."> explicitly.

PHPCS caching hides standard changes. .phpcs-cache keys on file contents and sniff set; after editing your ruleset or upgrading the standard (especially 0.4.x → 0.5.0) delete it (rm .phpcs-cache or --cache=0 for a run). Otherwise you will chase violations that "randomly" persist or vanish, and you will not see the new sniffs fire at all.

Old sniffs misread PHP 7.4+ syntax. Typed properties, arrow functions, nullable types, and especially PHP 8 attributes and match expressions post-date the base standard. Expect false positives on \Attribute declarations, readonly promotion, and union types. Check what php_version you can set — if the standard includes PHPCompatibility, --runtime-set php_version 70400 avoids a swath of spurious warnings; if it does not, suppress the affected sniff by name in your project ruleset rather than excluding files.

Blade and generated files. phpcs cannot parse .blade.php, and --extensions=php will happily try. Keep Blade out of <file> paths, and exclude _ide_helper.php, *.php in storage/framework/views, and published vendor stubs — these are generated and unfixable.

phpcbf is not safe on untested code — and v0.5.0 made it more aggressive. It now reorders imports, splits long lines, reformats ternaries, inserts trailing commas, marks closures static, and rewrites docblock types. On files with no test coverage, run it in isolation and diff carefully; on Laravel service providers and config/ arrays it can produce churn that obscures real changes in review, or (see the static-closure note) change behaviour outright.

Vendor or trim the standard rather than extending it. Given the low release cadence and the opinion-heavy additions in v0.5.0, the highest-leverage move is still to copy ruleset.xml into your own tools/phpcs/ directory, prune sniffs you disagree with, and reference PSR-12 directly. You get the same intent, escape the 2019 dependency lock, and no longer take CI-breaking changes from a package where a minor bump is allowed to add rules. If a full fork is too much, the <exclude name="..."/> + exact version pin combination gets you most of the way there.

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.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource