DEV Community

João Brandão
João Brandão

Posted on

💅 Automatically Format PHP Code

I love to have everything organised and to keep the code as clean as possible. And to do this by hand it's just really boring... And let's be honest it's also something from the past century because there are a lot of useful tools to beautifully help us keeping our beautiful code organised! 🙌

In this post, I'll show you how do I setup my PHP projects to be automatically formatted. 👀

1. Setup Formatter

1.1. Install the package php-cs-fixer

composer require friendsofphp/php-cs-fixer
Enter fullscreen mode Exit fullscreen mode

1.2. Create a .php_cs file on the root of your project

<?php

$finder = \PhpCsFixer\Finder::create()
    ->in(__DIR__)
    ->exclude(['bootstrap', 'storage', 'vendor'])
    ->name('*.php')
    ->ignoreDotFiles(true)
    ->ignoreVCS(true);

return PhpCsFixer\Config::create()
    ->setRules([
        '@PSR2' => true,
        'array_syntax' => ['syntax' => 'short'],
        'ordered_imports' => ['sortAlgorithm' => 'length'],
        'no_unused_imports' => true,
    ])
    ->setFinder($finder);
Enter fullscreen mode Exit fullscreen mode

In this example, here's what will happen:

  • bootstrap, storage and vendor directories will not be formatted.
  • All *.php files will be considered.
  • PRS2 rules are the ones that are going to be used!
  • Arrays like array() will be transformed to [].
  • Import statements will be ordered by their length to give that pyramid effect.
  • Unused imports will be removed.

Check the package documentation and change according your needs!

1.3. Add a script to your composer.json file

"scripts": {
    "format": "vendor/bin/php-cs-fixer fix"
}
Enter fullscreen mode Exit fullscreen mode

1.4. Run it

composer format
Enter fullscreen mode Exit fullscreen mode

Check the following basic example!

<?php

namespace Package\Services;

// Unwanted space here!
use Package\Box;
use Illuminate\Support\Facades\Session as LaravelSession; // This should be the last!
use Package\Contracts\SomeInterface;

class SessionService implements SomeInterface
{
        // Unwanted space here!
    public function load(): Box
    {
        return LaravelSession::has(Box::class)
          ? LaravelSession::get(Box::class)
          : new Box();
    }
}
Enter fullscreen mode Exit fullscreen mode
  • Only 1 space after namespace.
  • LaravelSession use line moved to the final import because of its length.
  • Removed an empty line before load function.
  • Added an empty line to the end of the file.
<?php

namespace Package\Services;

use Package\Box;
use Package\Contracts\SomeInterface;
use Illuminate\Support\Facades\Session as LaravelSession;

class SessionService implements SomeInterface
{
    public function load(): Box
    {
        return LaravelSession::has(Box::class)
          ? LaravelSession::get(Box::class)
          : new Box();
    }
}

Enter fullscreen mode Exit fullscreen mode

2. Make it run automatically

Now you can run it using composer. But that only means you can run the command... by hand!
Ideally would be to add this to your CI/CD pipeline alongside your tests! But most of the times, at least for me, I don't have a pipeline setup for really small projects like packages.

So I just use husky-php! This is a package for PHP to work with git hooks just like NPM's husky.

2.1. Install husky-php

composer require --dev ccinn/composer-husky-plugin ccinn/husky-php
Enter fullscreen mode Exit fullscreen mode

2.2. Add the hooks to composer.json

Check the package's documentation if you want to use other hooks!
Normally I just use pre-commit for formatting and pre-push for testing.

{
  "hooks": {
    "pre-commit": "composer format",
  }
}
Enter fullscreen mode Exit fullscreen mode

Now when you commit your code, composer format will run automatically! 🚀

I really hope that this is as useful for you as it was for me! 👋

Top comments (0)