💅 Automatically Format PHP Code

João Brandão
3 min readJan 28, 2021

--

I love to have everything organized 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 organized! 🙌

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

Photo by rashid khreiss on Unsplash

1. Setup Formatter

1.1. Install the package php-cs-fixer

composer require friendsofphp/php-cs-fixer

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);

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"
}

1.4. Run it

composer format

Check the following basic example!

<?phpnamespace Package\\Services;// Unwanted space here!
use Package\\Box;
// This should be the last!
use Illuminate\\Support\\Facades\\Session as LaravelSession;
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();
}
}
  • 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.
<?phpnamespace 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();
}
}

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

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",
}
}

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! 👋

--

--