hosmelq / php-coding-standard
Opinionated ECS, Rector, and PHPStan presets for PHP and Laravel packages and applications.
Requires
- php: ^8.4
- driftingly/rector-laravel: ^2.7
- friendsofphp/php-cs-fixer: ^3.95
- nesbot/carbon: ^3.15
- phpstan/extension-installer: ^1.4
- phpstan/phpstan: ^2.3
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-strict-rules: ^2.1
- rector/rector: ^2.7
- spaze/phpstan-disallowed-calls: ^4.15
- symplify/easy-coding-standard: ^13.3
- thecodingmachine/phpstan-safe-rule: ^1.4
- thecodingmachine/safe: ^3.4
- ticketswap/phpstan-error-formatter: ^1.3
- tomasvotruba/type-coverage: ^2.5
Requires (Dev)
- ergebnis/composer-normalize: ^2.54
- pestphp/pest: ^5.3
- pestphp/pest-plugin-agent: ^5.0
- pestphp/pest-plugin-rector: ^5.0
- shipmonk/composer-dependency-analyser: ^1.8
- symfony/process: ^8.1
Suggests
- pestphp/pest-plugin-rector: Required by the RECTOR_PEST preset (Pest 5+).
Provides
None
Conflicts
- fakerphp/faker: <1.24
- symfony/event-dispatcher-contracts: <2.5.4 || >=3.0 <3.5
- symfony/translation: <6.4.8 || >=7.0 <7.0.8
- symfony/translation-contracts: <2.5.4 || >=3.0 <3.5
Replaces
None
README
Opinionated ECS, Rector, and PHPStan presets for PHP and Laravel packages and applications, with custom fixers that lay out code by line width.
Requirements
- PHP 8.4+
Installation
Allow the PHPStan extension installer, then install PHP Coding Standard with Composer:
composer config allow-plugins.phpstan/extension-installer true
composer require --dev hosmelq/php-coding-standard
The package includes every tool and extension the presets use, except Larastan. Laravel packages and applications require it themselves:
composer require --dev larastan/larastan
Choose a preset
Use the same row in every tool:
| Project | ECS | Rector | PHPStan |
|---|---|---|---|
| PHP package or application | ECS_PHP |
RECTOR_PHP |
phpstan-php.neon |
| Laravel package | ECS_LARAVEL_PACKAGE |
RECTOR_LARAVEL_PACKAGE |
phpstan-laravel-package.neon |
| Laravel application | ECS_LARAVEL_APP |
RECTOR_LARAVEL_APP |
phpstan-laravel-app.neon |
ECS and Rector presets are constants on HosmelQ\PhpCodingStandard\CodingStandard.
PHPStan presets are files in the package's config directory. Each Laravel
preset builds on the one above it. Larastan boots Laravel packages with Orchestra
Testbench, which they already require for their tests.
Configure the tools
Create ecs.php:
<?php declare(strict_types=1); use HosmelQ\PhpCodingStandard\CodingStandard; use Symplify\EasyCodingStandard\Config\ECSConfig; return ECSConfig::configure() ->withSets([CodingStandard::ECS_PHP]) ->withPaths([__DIR__.'/src', __DIR__.'/tests']);
Create rector.php. To apply Pest's coding style rules with Pest 5, require
pestphp/pest-plugin-rector and add CodingStandard::RECTOR_PEST:
composer require --dev pestphp/pest-plugin-rector
<?php declare(strict_types=1); use HosmelQ\PhpCodingStandard\CodingStandard; use Rector\Config\RectorConfig; return RectorConfig::configure() ->withSets([CodingStandard::RECTOR_PHP, CodingStandard::RECTOR_PEST]) ->withPaths([__DIR__.'/src', __DIR__.'/tests']);
Create phpstan.neon:
includes: - vendor/hosmelq/php-coding-standard/config/phpstan-php.neon parameters: paths: - src
Run the tools:
vendor/bin/rector process vendor/bin/ecs check --fix vendor/bin/phpstan analyse
Run Rector before ECS so ECS lays out Rector's changes. One ECS run is enough. PHPStan runs at level max with strict, deprecation,
safe function, disallowed call, and full type coverage rules. The Laravel
application preset also analyses app, bootstrap, config, database, and
routes. PHPStan caches its results in .cache/phpstan, so add .cache to
.gitignore.
Lay out code
The ECS presets keep code within 100 columns. Chains that fit join onto one line, and long lines break their outermost construct first:
$invoice = Invoice::factory() ->for($customer) ->createOne(); $response = $this->actingAs($user)->post(route('invoices.store'), ['number' => 'INV-001', 'currency' => 'USD', 'paid' => true]); if ($subscription->status === SubscriptionStatus::PastDue && $user->canManageBilling($organization)) {
Becomes:
$invoice = Invoice::factory()->for($customer)->createOne(); $response = $this->actingAs($user)->post(route('invoices.store'), [ 'number' => 'INV-001', 'currency' => 'USD', 'paid' => true, ]); if ( $subscription->status === SubscriptionStatus::PastDue && $user->canManageBilling($organization) ) {
- Long method chains with three or more calls put each call on its own line.
- Arguments, parameters, and arrays put each item on its own line with a trailing comma. A call's last associative array, or its only array, opens inside the call.
- Long conditions break before
&&,||,??,.,?, and:. - Long arrow functions move their body to the next line, starting with
=>. - Lists with
//comments between items put each item on its own line. - Test calls such as
it('title', function () {})keep their title and closure on one line. - Blank lines between consecutive variable assignments are removed.
Strings, comments, comparisons, and long test titles can stay longer than the line length.
Change the line length
Configure LineLengthFixer in ecs.php. The line length must be at least 80:
use HosmelQ\PhpCodingStandard\Fixer\LineLengthFixer; return ECSConfig::configure() ->withSets([CodingStandard::ECS_PHP]) ->withConfiguredRule(LineLengthFixer::class, ['line_length' => 120]);
Customize presets
Call withConfiguredRule(), withRules(), or withSkip() after withSets()
in ECS and Rector:
use PhpCsFixer\Fixer\Strict\StrictParamFixer; return ECSConfig::configure() ->withSets([CodingStandard::ECS_PHP]) ->withSkip([StrictParamFixer::class]);
In PHPStan, project parameters override the preset and lists are merged. Add
! after a key, such as paths!, to replace a list.
Review risky changes
Some rules change behavior, such as DeclareStrictTypesFixer,
MbStrFunctionsFixer, StrictComparisonFixer, and StrictParamFixer, and the
Laravel presets convert dates to Carbon. Review these changes, or skip a rule
with withSkip().
Add runtime dependencies
The package is a development dependency. If your code calls Safe\ functions or
uses Carbon, require thecodingmachine/safe or nesbot/carbon directly.
Development
Run the test suite with:
composer test
Changelog
See CHANGELOG.md for a list of changes.
Contributing
Pull requests are welcome. Please run the test suite before submitting changes.
License
The MIT License (MIT). Please see License File for more information.