Autopergamene
Using Prettier in PHP
Published 2 years ago
6mn to read
What is Prettier?
Originally from the Javascript ecosystem, if you're not familiar with it Prettier is a code formatter, which means it takes your code, and makes it as its namme indicates prettier. There are a lot of code formatters, and for a lot of languages – even Javascript has quite a few of them.
But Prettier is currently one of the most popular code formatters out there and it has spread to a lot of different languages already, for one simple reason: it gives zero fucks about how you think your code should be formatted. You can pass a few basic options to Prettier (indentation, max width, etc. the basics) but other than that, it will take your whole code and reformat it from scratch, disregarding any formatting decision you may have previously taken.
This may sound counter-intuitive but it tremendously reduces friction when writing code, because the more you trust Prettier and the more you stop worrying about formatting altogether. You just type code all in one disgusting line, you press save, and you have nicely formatted code. You stop thinking about indentation, manually adding commas, or placing things for maximum readability etc. This represents much more of a daily coding day than people realise because those are "micro interruptions" that are scattered and as such feel inconsequential, but once you go without them you realise how much they accumulate.
Prettier and PHP
So ok Javascript and a bunch of other front-end languages (CSS, Markdown, etc) have this tool now, but this is Serious Entreprise PHPâ„¢, we have Serious Entreprise Toolsâ„¢ to take care of our code style and PSRs and RFCs and all that, we don't just type code until it's pretty. What is this, Ruby?
At madewithlove we currently use (mainly but not only) PHP CS Fixer, however a quick glance at the list of the things it fixes puts into light the main reason I still use Prettier in addition to it: PCS conflates code "style" (how the code is formatted, how pretty it is) and coding style (how the code is written, how good it is). It will much more often fix the latter, in very PHP specific ways, but will do very little for the former besides a few blank lines and indentation rules.
How do you use it?
Most of the time Prettier would be added to the project's package.json
but since we want to use it in a PHP project we'll install it globally through NPM (or Yarn if you want). Next, as the PHP support is not yet stable we'll have to specifically install it into Prettier:
npm install --global prettier @prettier/plugin-php
Once Prettier is installed, you can quickly try it out on one or more files by just invoking it on it (eg prettier somefile.php
or prettier src/**.php
). If I give it some kind of horrendous PHP code badly formatted per example:
<?php
namespace Foobar;
class SomeClass {
public function getCallbacks() {
return array( function () {return $this->firstName;},
function () {
return $this->callSomeMethod('foo')->andThenOtherMethod( Bar::withSome("arguments"),
$andShit );
});
}}
If you run prettier bad.php
it will return the formatted code. You could then pass the --write
option to write the result directly to the file.
<?php
namespace Foobar;
class SomeClass
{
public function getCallbacks()
{
return array(
function () {
return $this->firstName;
},
function () {
return $this->callSomeMethod('foo')->andThenOtherMethod(
Bar::withSome("arguments"),
$andShit
);
}
);
}
}
Where it gets interesting is that because Prettier rewrites the code, it constantly adapts. If there was a third method call, if the configured max width was different etc. it would format the code differently. This is a key difference with the formatting PHPStorm or PCS would give you because they follow very consistent rules: how to break down arguments, methods, classes etc depending on their width, etc.
Prettier doesn't do that, when it formats the code it barely even knows that it is formatting PHP code because it purely translates it into an abstract tree and formats it based on how readable it expects the output to be. It doesn't fully know what it is formatting, just where it can add breaks and newlines.
So you might disagree with the final output file but that would be missing the point, which is to stop caring about whether you agree or disagree in the first place.
How do you use it without having to type shit in the terminal?
Because Prettier is such a widely adopted tool, wherever Prettier is supported you can use it to format PHP code there (as long as it correctly uses the prettier you installed @prettier/plugin-php
on). However because we often follow some Symfony rules that would clash with the way Prettier reformats (since it does so according to PSR2), I instead recommend to add Prettier to your precommit pipeline/CI/etc. Both aren't incompatible (reformat on save and on commit) but the latter is the safest way.
You can use various tools for that, such as GrumPHP, but the most straightforward way remains the following:
"scripts": {
"lint": ["prettier src/**/* --write", "php-cs-fixer fix"]
}
Be careful however that while Prettier is very fast to run, PCS takes a lot more time so keep the formatting on save for Prettier.
That doesn't look worth it at all
Ok so it reformats a few lines, PHPStorm can do that too without another tool
Saying Prettier just reformats code would be very reductive, and it would be ignoring the pros that it brings on its own:
- It speeds up the time spent writing code by a huge factor. I talked about this a bit before but it's not just the time spent formatting your code that is lost right now, it's the time even thinking about it: what is the most readable way to split these lines? How can I best carefully arrange these characters so that they're easy to read? It's a whole mental load that suddenly goes away and you never look back.
- Prettier is insanely fast, like almost instantaneously fast. Comparing it to tools like PCS or PCF is night and day because they're not even booted by the time Prettier is done formatting your code, which is why the whole "format on save" paradigm is so important here compared to other tools
- It supports a shitload of languages, once you're used to letting Prettier reformat your code you can let it loose on a huge chunk of your codebase. The website lists the supported languages but it's very easy to setup a command such as this
prettier '{src/**,.}/*.{js,php,md,json,yml}'
which will format most files in your codebase, even READMEs, even fixture files. It even knows how to properly write YAML file, a knowledge long lost in the Symfony Wars of 2009.
Is it ready yet?
Prettier inherently changes the way you code, and it is coming to more and more languages besides PHP (such as Python). In the span of a few months, Prettier almost single handedly ended most formatting wars happening in the JS ecosystem; people went from entire tirades about trailing semicolons to #justuseprettier.
So while the tool is not released to the public yet, I am very much excited for when it does and to see if it has the same effect on the PHP community, even in a smaller way. I think our community has spent literal decades arguing on how to format code, to the point we needed a whole committee to regulate on it. And I think it's time we as developers all go over this and start just letting tools do these menial inconsequential tasks that we should have delegated to them entirely by now.
So stop worrying about whether to put this brace on this line or the next, on whether you should put spaces around parentheses or whatever. Just write your code, and let Prettier (or another tool) worry about the rest because nobody's scouring the market for people who are expert at neatly arranging braces. That's not your job.
"But the code would have been more readable had the argument been on a separate li–
I know, it's ok. Prettier will get better, it constantly does. But I repeat: this is not your job.