Updated ECS YAML to PHP configuration since ECS 8.
Legacy code prevention, lines automated and clear naming of classes in huge projects. That all is coming to Coding Standard 4 (still in alpha).
Are you curious what work will now these 4 news fixers handle for you? Look inside.
I'm so happy to announce this fixer, because it saved my so many times and also motivates me to use decoupling to smaller, SRP classes.
If you use LineLengthSniff
, you know it's painful to fix every error report it makes.
use PHP_CodeSniffer\Standards\Generic\Sniffs\Files\LineLengthSniff;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(LineLengthSniff::class)
->property('absoluteLineLimit', 120);
};
The most typical use case is constructor dependencies. You code start small:
public function __construct(OneLittleDependency $oneLittleDependency)
{
}
Then it grows...
public function __construct(OneLittleDependency $oneLittleDependency, AnotherLittleDependency $anotherLittleDependency)
{
}
...and grows...
public function __construct(OneLittleDependency $oneLittleDependency, AnotherLittleDependency $anotherLittleDependency, $someParameter)
{
}
...sniff screams, so you inline it...
public function __construct(
OneLittleDependency $oneLittleDependency,
AnotherLittleDependency $anotherLittleDependency,
$someParameter
) {
}
...then you refactor and merge 2 services to 1...
public function __construct(
OneLittleDependency $oneLittleDependency,
$someParameter
) {
}
...and that is inconsistent and has no reason to be inlined, so you inline it...
public function __construct(OneLittleDependency $oneLittleDependency, $someParameter) {
}
...and that is one of many reasons people don't like to decouple classes and keep them small.
There are other cases, where parameters, arguments or array items can change up and down:
-$someObject = new SomeClass(
- $shortArg
-);
+$someObject = new SomeClass($shortArg);
-$someArray = ['superlooongArgumentsover120chars', 'superlooongArgumentsover120chars', 'superlooongArgumentsover120chars'];
+$someArray = [
+ 'superlooongArgumentsover120chars',
+ 'superlooongArgumentsover120chars',
+ 'superlooongArgumentsover120chars'
+];
What if I told you that you'll have to never deal with this manually. Ever!
Welcome LineLengthFixer
.
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symplify\CodingStandard\Fixer\LineLength\LineLengthFixer;
return function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(LineLengthFixer::class);
};
As you guessed, this fixer works with 120 chars as maximum line-size... by default ↓
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symplify\CodingStandard\Fixer\LineLength\LineLengthFixer;
return function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(LineLengthFixer::class)
->call('configure', [[
'max_line_length' => 100, # default: 120
'break_long_lines' => true, # default: true
'inline_short_lines' => false, # default: true
]]);
};
It started as one simple static method. A helper method. They say: it's ok to use static methods, when you know when to use them. And that's how cancer started to spread slowly and lethally through Symplify code.
One day you wake up and from 1 static method is 60 static factories all over your code - Dependency Injection for very poor. And that not the worst. When all code works and is easy to maintain, 1 static method can't hurt it, right?
Well until you need to replace one of nested dependencies that requires few more classes. And then you realized your work is to basically manually maintain dump of dependency injection container and that you're not coding anymore.
It took weeks to get from this position back to clear dependency injection and I don't want to do it ever again. That's why this PHPStan rule was born.
rules:
- Symplify\CodingStandard\Rules\NoClassWithStaticMethodWithoutStaticNameRule
ForbiddenStaticFunctionSniff
We all already know that &$references
are bad practise, since they increase cyclomatic complexity and hide dependency logic.
function someFunction(&$var)
{
$var + 1;
}
And that we should prefer explicit syntax:
function someFunction($var)
{
return $var + 1;
}
I though I would never meet them again, but they somehow pop-up in PRs. So we made a PHPStan rule for it:
# phpstan.neon
rules:
- Symplify\CodingStandard\Rules\NoReferenceRule
ClassNameSuffixByParentFixer
Often in the code of private companies there are classes like:
ProductSorter
ProductSorter
ProductSorter
If you use PhpStorm and open file shortcut, you know where I aim.
Now, imagine you want to update the Command that sorts Products by price to Redis database. Inside, it looks like this:
final class ProductSorter extends Command
{
// ...
}
I could also ask, which one is the interface and which is its implementation, but there is already checker for that.
Probably each of them manually until you find the right one, which really sucks. That why not only methods names, but also class names should be as descriptive and as deterministic as possible. Like this:
-final class ProductSorter extends Command
+final class ProductSorterCommand extends Command
{
// ...
}
And then you have clear class names, that you're able to distinguish without their content:
ProductSorterCommand
ProductSorterRepository
ProductSorterController
And that's exactly what ClassNameRespectsParentSuffixRule
helps you to do.
# phpstan.neon
rules:
- Symplify\CodingStandard\Rules\ClassNameRespectsParentSuffixRule
parameters:
symplify:
# it handles many default cases, but allows you to add your own
forbidden_parent_classes: []
Happy sniffing and fixing!
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!