Jump to content
Development

The power of Static Analysis.

As PHP developers, we all want to write clean, maintainable code that doesn’t break in production. But with larger projects, keeping track of potential issues and bugs can become increasingly difficult. This is where tools like static analysis can help out. By analysing your code without actually running it, static analysis can catch potential bugs and improve code quality before it even reaches production.

At Jump24, we’ve found that static analysis has been a powerful tool for improving our code quality as a team. In this post, we’ll discuss how we use PHPStan for static analysis in our day-to-day development, and how it has helped us catch potential issues early in the development process.

Choosing the right static analysis tool

Choosing the right static analysis tool is crucial for any project. We chose PHPStan as the tool to perform static analysis on our code. PHPStan is an open-source PHP static analysis tool that checks for potential errors in your code by analysing the PHP files.

PHPStan is a great choice for us because it has a wide range of rules that can catch potential issues in our code. Additionally, we’ve created custom rules to suit our specific needs. For example, we’ve created custom rules that enforce our internal coding standards and prevent certain types of mistakes that we’ve seen constantly in codebases we’ve been asked to take over and maintain. When we were comparing PHPStan and Psalm we found that PHPStan had much better support for Laravel thanks to Larastan, so whenever we’re using PHPStan we also install Larastan at the same time.

Using PHPStan in day-to-day development

Using PHPStan in our day-to-day development process has been crucial for catching potential issues before they make it to production. For us to achieve this there are a few steps that we first need to take to be able to use PHPStan in our project.

Setting up PHPStan

Firstly you will need to install PHPStan a detailed explanation of how to do that can be found here

composer require --dev phpstan/phpstan

After this you can either run the command with the required parameters or as we do, create a phpstan.neon file which holds the configuration for your static analysis.

Example phpstan.neon File

parameters:
    level: 9
    paths:
        - app
        - config
        - routes
        - database/factories
    reportUnmatchedIgnoredErrors: true
    checkMissingIterableValueType: false
    checkModelProperties: true
    checkUnusedViews: false

    excludePaths:
        - tests
        - vendor
        - _ide_helper.php
        - _ide_helper_models.php
        - .phpstorm.meta.php
        - node_modules

As you can see in this file we’re setting the level of analysis we would like to run on the code base (highest is 9), the paths we would like the tool to analyse and we have set a few small config items that we choose to have set by default in our code base. There is also a excludePaths section which allows us to tell the tool not to analyse the files or folders listed here.

As well as this it’s possible for your phpstan.neon file to include another file. At Jump24 we have a base phpstan.neon file that exists in our standards package that we use in all our Laravel projects. This file sets up a number of basic rules that we always want to have present in our analysis of a codebase.

Once we’ve installed the package and added the relevant file we then use a simple composer command to run PHPStan on our codebase:

First update your composer.json file adding the following into the scripts section

"scripts": {
      "phpstan": [
          "Composer\\Config::disableProcessTimeout",
          "vendor/bin/phpstan analyse --memory-limit=4G"
      ],
  }

Then run the following command in your terminal to analyse your code.

composer phpstan

This command runs PHPStan on all PHP files in your project that have been defined in your configuration file from above, and outputs a report of any potential issues it finds.

One of the benefits of using PHPStan is that it can catch potential issues with type hinting and type safety. For example, consider this very simple function that adds two integers together:

function addTwoNumbers(int $numberOne, int $numberTwo): int {
  return $numberOne + $numberTwo;
}

$result = addTwoNumbers(1, '2');

This code will run without any errors, but it’s clearly incorrect as we’re using the wrong type for the second parameter being passed to the method addTwoNumbers, we’re passing a string when the method requires a int. Due to PHP not being a strict language by default this code will still run and you will get the correct result. Now if you make the following change to the code above.

declare(strict_types=1);

function addTwoNumbers(int $numberOne, int $numberTwo): int {
  return $numberOne + $numberTwo;
}

$result = addTwoNumbers(1, '2');

And then try and run the code you will get the following error

Fatal error: Uncaught TypeError: Argument 2 passed to addTwoNumbers() must be of the type int, string given

If you run this code through your static analysis tool you will get an error similar to this

Parameter #2 $numberTwo of function addTwoNumbers() expects int, string given.

Though this is a simple example it shows how important using tools like this is and how easy it is for type errors to slip in. As soon as you turn strict_types=1 on for your codebase you might start to see more and more of this type of error occur, particularly when working with an old codebase that you’re trying to modernise. This is where tools like Rector also become super useful.

Adding to an existing project

If you’re taking over a project or you have a an old project that you’d like to add PHPStan to but you’re afraid of the amount of errors you might get when you go to run the command don’t fret, you can start off with a baseline file that takes the current errors and puts them into this file which you will then add to your phpstan.neon file as shown below

includes:
    - phpstan-baseline.neon

parameters:
    level: 9
    paths:
        - app
        - config
        - routes
        - database/factories
    reportUnmatchedIgnoredErrors: true
    checkMissingIterableValueType: false
    checkModelProperties: true
    checkUnusedViews: false

    excludePaths:
        - tests
        - vendor
        - _ide_helper.php
        - _ide_helper_models.php
        - .phpstorm.meta.php
        - node_modules

by adding this file the next time you run static analysis PHPStan will not warn you about the current errors and only on new errors on the new code you write and change. This gives you the ability to quickly add it to these kind of projects and improve them over time. Head to the PHPStan docs to find out more about the baseline

Continuous Integration with PHPStan

Running your static analysis tool during your development lifecycle is very important to help you pickup issues early and keep that feedback loop small. It’s also really important to make sure your CI tools are also running the same analysis of your code to make sure that nothing slips through. We typically use Github for our code repositories so we have Github Actions setup running analysis on each PR that a developer puts in.

Here is a typical example of a very basic Github Action workflow that runs PHPStan:

name: PHPStan
on: pull_request

jobs:
  phpstan:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v2

    - name: Install dependencies
      run: composer install

    - name: Run PHPStan
      run: composer run phpstan

By having our CI run the analysis we’re stopping issues from getting into our releases which helps us maintain a higher standard of coding.

Improved code quality as a team

Overall using tools like PHPStan has been a game-changer for the team. By catching potential issues early in the development process, we’ve been able to avoid potential bugs in production and ensure that our code is much stronger typed, after all who doesn’t like a stronger typed codebase?

Want to start your next Laravel project?

Looking to start your next Laravel project? We’re passionate about creating top-quality web applications that stand out from the crowd. Let our skilled development team work with you to bring your ideas to life! Get in touch today and let’s get started!

Start your project

Laravel Partner

Since 2014, we’ve built, managed and upgraded Laravel applications of all types and scales with clients from across the globe. We are one of Europe’s leading Laravel development agencies and proud to support the framework as an official Laravel Partner.

Get in touch

Vue Experts

We use Vue alongside Laravel on many of our projects. We have grown our team of experts and invested heavily in our knowledge of Vue over the last five years.

Get in touch
Top