symplify / easy-coding-standard
Use Coding Standard with 0-knowledge of PHP-CS-Fixer and PHP_CodeSniffer
Requires
- php: >=7.2
Requires (Dev)
None
Suggests
- ext-dom: Needed to support checkstyle output format in class CheckstyleOutputFormatter
Provides
None
Conflicts
- friendsofphp/php-cs-fixer: <3.95.20
- phpcsstandards/php_codesniffer: <4.0.4
- symplify/coding-standard: <13.0
Replaces
None
This package is auto-updated.
Last update: 2026-09-05 10:46:39 UTC
README
Easy Coding Standard (ECS) is a single tool that runs PHP_CodeSniffer and PHP-CS-Fixer rules together, configured through one simple PHP file.
Note
This is the deployed package. Development happens in the ecs-src repository - report issues and send pull requests there.
Killer Features
- Install on any PHP 7.2-PHP 8.5 project with any dependencies
- Blazing fast with parallel run out of the box
- Use PHP_CodeSniffer or PHP-CS-Fixer - anything you like
- Use prepared sets and PHP CS Fixer sets to save time
Install
composer require symplify/easy-coding-standard --dev
Usage
vendor/bin/ecs
On the first run, ECS creates ecs.php config file with directories and first rule to kick off.
Then you can run again to see the suggested diffs:
vendor/bin/ecs
Want to check specific paths instead of the configured ones? Pass them as arguments:
vendor/bin/ecs src tests
To actually fix your code, add --fix:
vendor/bin/ecs --fix
That's it!
Configure
Most of the time, you'll be happy with the default configuration. The most relevant part is configuring paths, checkers and sets:
use PhpCsFixer\Fixer\ArrayNotation\ArraySyntaxFixer; use PhpCsFixer\Fixer\ListNotation\ListSyntaxFixer; use Symplify\EasyCodingStandard\Config\ECSConfig; return ECSConfig::configure() ->withPaths([__DIR__ . '/src', __DIR__ . '/tests']) // start slow with sole rules ->withRules([ ListSyntaxFixer::class, ]) ->withConfiguredRule( ArraySyntaxFixer::class, ['syntax' => 'long'] ) // apply full set ->withPreparedSets(psr12: true);
Do you want to check all *.php files in your root (ecs.php, rector.php etc.)? Instead of listing them one by one, use ->withRootFiles() method:
use Symplify\EasyCodingStandard\Config\ECSConfig; return ECSConfig::configure() ->withPaths([__DIR__ . '/src', __DIR__ . '/tests']) ->withRootFiles();
Prepared Sets
->withPreparedSets() bundles curated rule sets. Enable the whole common set, or pick single topics:
use Symplify\EasyCodingStandard\Config\ECSConfig; return ECSConfig::configure() ->withPaths([__DIR__ . '/src', __DIR__ . '/tests']) ->withPreparedSets( arrays: true, spaces: true, namespaces: true, docblocks: true, controlStructures: true, comments: true, casing: true, cleanup: true, );
| Set | What it covers |
|---|---|
arrays |
array syntax, spacing, trailing commas, indentation |
spaces |
whitespace, operator/type spacing, blank lines |
namespaces |
imports ordering, unused/needless-alias imports |
docblocks |
phpdoc tags, types, alignment, cleanup |
controlStructures |
control flow, casing, operators, class structure |
comments |
comment style, spacing, empty-comment cleanup |
casing |
native function/type, magic method, literal casing |
cleanup |
dead statements, useless returns/casts, unused closure imports |
Or enable everything at once with ->withPreparedSets(common: true).
Gradual Adoption with Levels
Want to adopt a coding standard step by step instead of all at once? Use with*Level() methods to start from the safest rules and raise the level as your codebase catches up:
use Symplify\EasyCodingStandard\Config\ECSConfig; return ECSConfig::configure() ->withPaths([__DIR__ . '/src', __DIR__ . '/tests']) ->withSpacesLevel(0) ->withArrayLevel(0) ->withControlStructuresLevel(0) ->withDocblockLevel(0);
Each level enables the first N+1 rules from a curated list, ordered from safest to most invasive. Bump the number once your codebase is clean on the current level.
How to Skip Files/Rules?
Love the sets of rules, but want to skip single rule or some files?
use Symplify\EasyCodingStandard\Config\ECSConfig; return ECSConfig::configure() ->withSkip([ // skip single rule ArraySyntaxFixer::class, // skip single rule in specific paths ArraySyntaxFixer::class => [ __DIR__ . '/src/ValueObject/', ], // skip directory by absolute or * mask __DIR__ . '/src/Migrations', // skip directories by mask __DIR__ . '/src/*/Legacy', ]);
Less Common Options
You probably won't use these, but they can give you more control over the internal process:
use Symplify\EasyCodingStandard\Config\ECSConfig; use Symplify\EasyCodingStandard\ValueObject\Option; return ECSConfig::configure() // file extensions to scan ->withFileExtensions(['php']) // configure cache paths and namespace - useful e.g. Gitlab CI caching, where getcwd() produces always different path ->withCache( directory: sys_get_temp_dir() . '/_changed_files_detector_tests', namespace: getcwd() // normalized to directory separator ) // print contents with specific indent rules ->withSpacing(indentation: Option::INDENTATION_SPACES, lineEnding: PHP_EOL) // modify parallel run ->withParallel(timeoutSeconds: 120, maxNumberOfProcess: 32, jobSize: 20);
Mentioned values are default ones.
Controlling Output Format
You may want to use ECS to generate reports for third-party tooling.
We currently provide formatters for:
console: Human-oriented printing à la PHP CS Fixer.json: A custom JSON blob for arbitrary tooling.checkstyle: Useful for Github Action Reports.
You can use the output format option as below
vendor/bin/ecs --output-format=checkstyle
FAQ
How do I clear cache?
vendor/bin/ecs --clear-cache
How can I see all used rules?
vendor/bin/ecs list-checkers
Do you look for json format?
vendor/bin/ecs list-checkers --output-format json
How to Migrate from another coding standard tool?
Do you use another tool and want to migrate? It's pretty straightforward - here is "how to":
- for PHP_CodeSniffer
- and PHP CS Fixer.