Lint Your PHP in Vim
Tags: vim, productivity, beginners, php
Published: 2019-07-02 15:40:50

> The objective of cleaning is not just to clean, but to feel happiness living
> within that environment.
>
> ~ Marie Kondo

Everyone who has written PHP for a while ends up confronted with messy code. The gentle learning curve, the forgiving type system, and the easy execution model all lend themselves to writing PHP that's quick, dirty, and eventually frustrating.

In 2013, the PHP Framework Interoperability Group ([PHP-FIG](https://www.php-fig.org)) adopted PSR-2, a standard for code which was intended to "reduce cognitive friction when scanning code from different authors." The result? Reading PHP code by different authors in different projects has never been easier. Whether you're diving into your workplace's proprietary code or Laravel's Eloquent ORM code, you'll find that it's readable (even if not quite understandable!).

Our goal here is going to be setting up automated tools in Vim to clean up your code as you write. By making it part of your regular flow and getting quick feedback, you'll be able to write your code with the confidence that in a year or two when you open up this file again, you'll still be able to read it!

> If you clean your bathroom every day, you never have to clean your bathroom.
>
> ~ Lindy West's Mother, _Shrill: Notes from a Loud Woman_

We're going to take advantage of some existing tools: PHP-Code Sniffer
(PHP-CS) and PHP-CS-Fixer.

## Installing PHP-CS

To add PHP-CS to your project using composer, run:

```
composer require --dev "squizlabs/php_codesniffer=\*"
```

By default, PHP-CS checks against the PEAR coding standard. However it ships with several other configurations, including `PSR2`. We can run PHP-CS to check for standards violations using the `phpcs` command.

```
./vendor/bin/phpcs --standard=PSR2 path/to/file
```

However, since we're also looking to standardize and automate this in our
project, we are going to create a file in our project that configures PHP-CS. The file that PHP-CS looks for is a `phpcs.xml` file.

```
<?xml version="1.0"?>
<ruleset name="Custom Standard" namespace="MyProject\CS\Standard">
  <description>Our custom coding standard based on PSR-2</description>
  <rule ref="PSR2"/>
</ruleset>
```

Since we're using the PSR-2 standard, our ruleset is pretty simple. [The PHP-CS documentation shows many more options, including the ability to exclude some files or rules, or include rules from other coding standards.](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Annotated-Ruleset)

Now when we run `.vendor/bin/phpcs` we're going to get the PSR-2 coding standard checked against every one of our files based on our `phpcs.xml` file!

## Installing PHP-CS-Fixer

Generally we don't only want our computer to tell us when something is wrong, we can also get it to fix our coding issues for us! The tool for this is PHP-CS-Fixer.

Again we'll use Composer to install PHP-CS-Fixer

```
composer require --dev friendsofphp/php-cs-fixer
```

And we'll be able to run it using `.vendor/bin/php-cs-fixer fix path/to/file`.

We'll also create a `.php_cs.dist` file in our project so we can standardize the rules we're going to enforce. The file will look like this:

```
<?php

$finder = PhpCsFixer\Finder::create();

return PhpCsFixer\Config::create()
    ->setRules([
        '@PSR2' => true,
    ])
    ->setFinder($finder)
;
```

## Integrating With Vim

To bring these tools into Vim, we're going to rely on [the plugin ALE](https://github.com/w0rp/ale). ALE is capable of a lot of things, including linting (with PHP-CS), fixing (with PHP-CS-Fixer), and even deeper IDE-like features using the Language Server Protocol (going to get into that in a later post).

First, [install ALE based on your own Vim setup](https://github.com/w0rp/ale#installation).

Then we want to add some configuration so ALE knows where to look for our tools. Add the following to your project's `.vimrc` assuming you're using `:exrc` to allow for project-based vim configuration.

```
let g:ale_php_phpcs_executable='./vendor/bin/phpcs'
let g:ale_php_php_cs_fixer_executable='./vendor/bin/php-cs-fixer'
let g:ale_fixers = {'php': ['php-cs-fixer']}
```

And that should set up ALE with PHP-CS and PHP-CS-Fixer! PHP-CS should be running asynchronously, and the issues it finds will pop up as you type.

In order to run PHP-CS-Fixer, use the command `:ALEFix` in a file, which will run the fixer and write those changes.

You can also run the fixers every time you save by adding `let g:ale_fix_on_save` in your `.vimrc` file.