New in Symplify 3: 4 Time-saving Coding Standard Checkers

This post was updated at August 2020

Updated with ECS 5, Neon to YAML migration and checkers to services migration.

ImportNamespacedNameFixer was removed in favor of ReferenceUsedNamesOnlySniff from slevomat/coding-standard

Updated with ECS to Rector rules and PHP configuration. Removed UnusedPublicSniff, that does not exist anymore. Use Rector dead-code set instead.


Coding Standard in Symplify 3 brings checkers build from practical use in PHPStorm. It can do lot of work for you, like add getters, remove trailing spaces, but has still some room for automation and improvement.
I already wrote about doc block cleaner fixer and here 4 more checkers, that saves you from monkey-typing and let you focus on algorithms.

Starting with the simple checkers and moving to those, which save you even hours of manual work.

1. Absolutely Require and Include

  Check the pull-request

You probably recognize this:

require 'vendor/autoload.php';

Why is this bad? It promotes relative paths by default, supports magic path resolving and can cause errors, because we expects existing file by default. You can easily end-up in ambiguous file paths like:

var_dump($relativeFile);
"/var/path/fileName.php"
# or
"/var//path/fileName.php"
# or
"/varpath/fileName.php"

Of course there are cases when using absolute paths is not suitable, like templates in Symfony application, but when we know the absolute path we should prefer it:

-require 'vendor/autoload.php';
+require __DIR__.'/vendor/autoload.php';

And that's what this Rector rule does for you:

<?php

// rector.php

declare(strict_types=1);

use Rector\CodingStyle\Rector\Include_\FollowRequireByDirRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $containerConfigurator): void {
    $services = $containerConfigurator->services();

    $services->set(FollowRequireByDirRector::class);
};


2. Empty Line after declare(strict_types=1)

  Check the pull-request

The next one started as issue PHP CS Fixer in January 2016 (if not earlier). The story continues in next issue, but final fixer is not in near sight.

Why all these issues? Official fixer modifies code like this:

-<?php
+<?php declare(strict_types=1);
-
 namespace Abc;

Which is not what we want.

BlankLineAfterStrictTypesFixer fixer was needed so EasyCodingStandard could refactor open-source packages without any manual work:

When the official fixer is finished, I'd be happy to use it and recommend it. But right now you can use:

<?php

// ecs.php

declare(strict_types=1);

use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symplify\CodingStandard\Fixer\Strict\BlankLineAfterStrictTypesFixer;

return static function (ContainerConfigurator $containerConfigurator): void {
    $services = $containerConfigurator->services();

    $services->set(BlankLineAfterStrictTypesFixer::class);
};

Which helps official fixer to keep the space:

-<?php
+<?php declare(strict_types=1);

 namespace Abc;

3. One Way To Use Namespace Imports

What do you think about this?

Import class is great PHPStorm feature. It sometimes does only partial imports, sometimes is unable to resolve conflict of 2 SameClass names and it still requires your time and attention to work.

If you don't care about this, your code can look like this:

<?php

namespace SomeNamespace;

final class SomeClass extends \SubNamespace\PartialNamespace\AnotherClass
{
    public function getResult(): \ExternalNamespace\Result
    {
        $someOtherClass = new \SomeNamespace\PartialNamespace\SomeOtherClass;
        // ...
    }
}

If you do care - which is probably why you're reading this post - you'd prefer code like this:

 <?php

 namespace SomeNamespace;

+use ExternalNamespace\Result;
+use SubNamespace\PartialNamespace\AnotherClass
+use SubNamespace\PartialNamespace\SomeOtherClass;

-final class SomeClass extends \SubNamespace\PartialNamespace\AnotherClass
+final class SomeClass extends AnotherClass
 {
-    public function getResult(): \ExternalNamespace\Result
+    public function getResult(): Result
     {
-        $someOtherClass = new \SomeNamespace\PartialNamespace\SomeOtherClass;
+        $someOtherClass = new SomeOtherClass;
         // ...
     }
 }

To enable this behavior, add one parameter to Rector config:

<?php

// rector.php

declare(strict_types=1);

use Rector\CodingStyle\Rector\Include_\FollowRequireByDirRector;
use Rector\Core\Configuration\Option;use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $containerConfigurator): void {
    $parameters = $containerConfigurator->parameters();
    $parameters->set(Option::AUTO_IMPORT_NAMES, true);
};


Do You Want More?

There are over 30 standalone checkers in Symplify\CodingStandard 3.0 with more added every release.

See visual examples in README and decide for yourself, which you like and which you don't.

Thanks @carusogabriel for the diff idea in README. It's brilliant!



Happy fixing and sniffing!