Setting up PHPCS and PreCommit Githooks to a Laravel Project

When we start the project, we always say “we will use proper coding standard and let’s do the code review”. Every time, when someone makes a pull request, we have to comment about coding standard errors all the time. Stop wasting time, let’s PHP_CodeSniffer do for you.

What’s the benefit of using PHP CodeSniffer?

PHP CodeSniffer shows you coding standard errors and phpcbf help fix you basic coding standard problems. By using PHP CodeSniffer, you don’t have to worry that much for the coding standard. When someone new comes to join the team, it’s much easier for him/her and for the rest of the team as well.

Setup PHP CodeSniffer

First, go to your terminal and install PHP CodeSniffer as your development package with the composer in your Laravel project. (You can use PHP CodeSniffer outside of PHP project as well. It’s for PHP Projects. But, we plan to use with Laravel. In the future, I gonna write an article base on this article.)

composer require --dev squizlabs/php_codesniffer

After you finish setting up, create a new simple controller like the following

<?php namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HelloController extends Controller{
}

And run phpcs on your project like the following…

./vendor/bin/phpcs app/Http/Controllers/HelloController.php
PHPCS Errors

You got PHPCS errors. There is a message which said *PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY* Which means, phpcbf can fix that bug you. Let’s run phpcbf on your project like the following…

./vendor/bin/phpcbf app/Http/Controllers/HelloController.php

Now, when you run phpcs you only got 2 errors instead of getting 3. Since phpcbffix that one error for you.

Opening brace of a class must be on the line after the definition

Now, when you check your controller, you will saw like the following.

<?php namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HelloController extends Controller
{
}

Now, we still left 2 errors. I hope you get the point of using PHPCodeSniffer.

Setup PHPCS Config

After you understand what’s phpcs. Now, let’s try to setup phpcs for our Laravel project. Create phpcs.xml on your Laravel document root and paste the following config

<?xml version="1.0"?>
<ruleset name="PSR2">
<description>The PSR2 coding standard.</description>
<rule ref="PSR2"/>
<file>app/</file>
<exclude-pattern>vendor</exclude-pattern>
<exclude-pattern>resources</exclude-pattern>
<exclude-pattern>database/</exclude-pattern>
<exclude-pattern>storage/</exclude-pattern>
<exclude-pattern>node_modules/</exclude-pattern>
</ruleset>

Since Laravel uses PSR2 coding stand we use PSR2 coding stand and excluded vendor, resoruces, database, storage, node_modulesdirectory.

Now, when you run phpcs on your project directory it will check with PSR2 coding standard and will show the errors to fix some of those errors, you just run phpcbf and it will help you fix. The rest which can’t fix from phpcbf need to be fixed by you or your teammate. Like that, everyone is happy to code on the PSR2 coding standard project.

Setup Git Commit PreHook Config

Every time before you commit your changes. You have to run phpcbf and phpcs . Sometimes, you forget. And you have to fix phpcs coding standard problem and commit/push again.

Is that ok for you? Nope, not really for me. There might be a better way, right? Yes, it’s called Git commit prehook. Let’s configure phpcs with git commit prehook.

Before we set up, let me explain a little bit about what I am trying to do. Every time, when I add and commit a PHP file which is under our phpcs.xml rules. It will run phpcbf and phpcs for us. If that fails, we have to fix those first. Otherwise, it will stop you from committing.

Now, you understand what I am trying to do. Let’s create a git-hooks folder on our project and add pre-commit file. And paste the folling code into pre-commit file.

#!/bin/sh

STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep ".php\{0,1\}$")

if [[ "$STAGED_FILES" = "" ]]; then
exit 0
fi

PASS=true

echo "\nValidating PHPCS:\n"

# Check for phpcs
which ./vendor/bin/phpcs &> /dev/null
if [[ "$?" == 1 ]]; then
echo "\t\033[41mPlease install PHPCS\033[0m"
exit 1
fi

RULESET=./phpcs.xml

for FILE in $STAGED_FILES
do
./vendor/bin/phpcs --standard="$RULESET" "$FILE"

if [[ "$?" == 0 ]]; then
echo "\t\033[32mPHPCS Passed: $FILE\033[0m"
else
echo "\t\033[41mPHPCS Failed: $FILE\033[0m"
PASS=false
fi
done

echo "\nPHPCS validation completed!\n"

if ! $PASS; then
echo "\033[41mCOMMIT FAILED:\033[0m Your commit contains files that should pass PHPCS but do not. Please fix the PHPCS errors and try again.\n"
exit 1
else
echo "\033[42mCOMMIT SUCCEEDED\033[0m\n"
fi

exit $?

The above code block explains what I am trying to do with git pre-commit hook. Run the following command

cp git-hooks/pre-commit .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit

and chmod +x .git/hooks/pre-commit . Like that, when you try to commit something which does not pass phpcs will be errors like the following.

PHPCS Errors when a user commits the code without checking PHPCS.

After, you finish fixing the problem. It will appear like the following…

When user pass the phpcs

That’s it for now. Comments, if you are not clear about the process. I will try to respond as soon as possible. Clap 👏 if this post helps you.

Buy me a coffee if my article is useful for you ☕️