How to Migrate From PHP CS Fixer to ECS in 6 Steps

This post was updated at January 2023 with fresh know-how.
What is new?

Updated with ECS 12 and ECSConfig::configure() simple way to work with configs.


We looked at how to migrate from PHP_CodeSniffer to Easy Coding Standard on Monday. But what if your weapon of choice is PHP CS Fixer and you'd to run also some sniffs?

There are a few simple A → B changes, but one has to know about them or will get stuck. Let's learn about them.

ECS is a PHP CLI tool that combines PHP_CodeSniffer and PHP CS Fixer. It's easy to use from scratch:

composer require symplify/easy-coding-standard --dev

ECS uses simple PHP config format:

// ecs.php
use Symplify\EasyCodingStandard\Config\ECSConfig;

return ECSConfig::configure()
    ->withPaths([__DIR__ . '/src');
    ->withPreparedSets(psr12: true);

And runs as CLI command:

vendor/bin/ecs

Do you use PHP-CS-Fixer on your project and want to switch? Let's jump right into it:

1. From String Codes to Autocompleted Classes

You use string references like strict_types in your .php_cs file. You need to remember them, copy paste them from README and copy-paste them correctly.

return PhpCsFixer\Config::create()
    ->setRules([
        'strict_types' => true,
    ])
    ->setFinder($finder);

That can actually cause typos like:

 return PhpCsFixer\Config::create()
     ->setRules([
-        'strict_types' => true,
+        'declare_strict_types' => true,
     ])
     ->setFinder($finder);

How to do that in ECS? We use FQN class names instead. So you can check the rule class right from your IDE.

// ecs.php
use Symplify\EasyCodingStandard\Config\ECSConfig;
use PhpCsFixer\Fixer\Strict\DeclareStrictTypesFixer;

return ECSConfig::configure()
    ->withRules([
        DeclareStrictTypesFixer::class
    ]);

No more typos with strong native class reference.

2. From notPath() to withSkip() Method

If you'd like to skip nasty code from being analyzed, you'd probably use this in PHP CS Fixer.

$finder = PhpCsFixer\Finder::create()
    ->exclude('somedir')
    ->notPath('my-nasty-dirty-file.php')
    ->in(__DIR__);

Do you need DeclareStrictTypesFixer to skip this file? Sorry, PHP CS Fixer will skip it for ever rule.

ECS solves this common case - to skip a file, just use skip parameter:

// ecs.php
use Symplify\EasyCodingStandard\Config\ECSConfig;
use PhpCsFixer\Fixer\Strict\DeclareStrictTypesFixer;

return ECSConfig::configure()
    ->withSkip([
        DeclareStrictTypesFixer::class => [
            __DIR__ . '/my-nasty-dirty-file.php',
            // you can add more files
            __DIR__ . '/Legacy/too-legacy-to-look-at.php',

            // or directories
            __DIR__ . '/Legacy',

            // or mask paths with fnmatch()
            __DIR__ . '/*/Command',
        ]
    ]);

Do you want to skip 1 fixer for all files?

// ecs.php
use Symplify\EasyCodingStandard\Config\ECSConfig;
use PhpCsFixer\Fixer\Strict\DeclareStrictTypesFixer;

return ECSConfig::configure()
    ->withSkip([
        DeclareStrictTypesFixer::class,
    ]);

Check README for more options to use in skip.

3. From .php_cs to PHP Config

PHP CS Fixer looks for .php_cs file in the root directory by default.

And ECS looks for ecs.php


What about non-default locations or names?

From:

vendor/bin/php-cs-fixer fix /path/to/project --config=custom/location.php --dry-run

to:

vendor/bin/ecs check /path/to/project --config custom/location.php

4. Configuring Fixer Values

From PHP configuration in PHP CS Fixer:

return PhpCsFixer\Config::create()
    ->setRules([
        'array_syntax' => ['syntax' => 'short'],
    ])
    ->setFinder($finder);

to withConfiguredRule() method in ECS:

// ecs.php
use Symplify\EasyCodingStandard\Config\ECSConfig;
use PhpCsFixer\Fixer\ArrayNotation\ArraySyntaxFixer;

return ECSConfig::configure()
    ->withConfiguredRule(ArraySyntaxFixer::class, [
        'syntax' => 'short',
    ]);

Nice and clear!

5. From no --dry-run to --fix option

From PHP CS Fixer:

vendor/bin/php-cs-fixer fix --dry-run
vendor/bin/php-cs-fixer fix

to ECS equivalent:

vendor/bin/ecs check
vendor/bin/ecs check --fix

6. From @Rules to withPhpCsFixerSets() Method

Do you like to use standards like PSR-2 or even PSR-12?

From @strings in PHP CS Fixer:

$config = PhpCsFixer\Config::create()
    ->setRules([
        '@PSR2' => true,
    ]);

to autocompleted method in ECS:

// ecs.php
use Symplify\EasyCodingStandard\Config\ECSConfig;

return ECSConfig::configure()
    ->withPhpCsFixerSets(psr12: true);

That's it.


Happy coding!




Do you learn from my contents or use open-souce packages like Rector every day?
Consider supporting it on GitHub Sponsors. I'd really appreciate it!