Docker image that provides static analysis tools for PHP
Use the jakzal/phpqa Docker image to instantly run dozens of static analysis and code quality tools for your PHP codebase, including linters and fixers, without any installation.
This article is part of the code quality series:
- Markdown linter - solve formatting issue in md files
- Rector 1.0.0 🎉🎉🎉, my friend, my coach
- Docker image that provides static analysis tools for PHP
- Clean code - Linux Bash - Keep the number of function parameters as small as possible
- SQL - Formatting tool
- JSON - Online linter
- Format poorly formatted PHP code
- Python - Code Quality tools
- Git - pre-commit-hooks
- Validate your OpenAPI schema against the Belgif REST standards
Changelog

This article shows how to run a whole suite of PHP static analysis tools with zero installation via the jakzal/phpqa Docker image: composer normalize to reorder composer.json, composer-unused to spot unused dependencies, parallel-lint for syntax errors, php-cs-fixer and phpcbf for auto-formatting — plus how to pin a specific PHP version tag when scanning legacy codebases.
For years now, I'm using https://github.com/jakzal/phpqa to run a lot of static analysis tools on my PHP codebase.
The list of available tools is huge; see by yourself: Available tools.
In this blog post, we will see how we can take advantage of all these tools and increase the quality of our scripts.
First, as always when we need to learn new software, we must talk about how to install it. The answer is easy here: there is nothing to do. Oh? Really? For sure! jakzal/phpqa is a Docker image so we don't need to install it, just to run it once. During the first call, Docker will download it so, yeah, no installation at all. Thank you Docker!
Docker CLI reminder
As a reminder, the used Docker run command will always look like:
docker runto run a Docker image (Oh? Really?),-itto start Docker interactively, this will allow the script running in the container to ask you for some prompts f.i.,--rmto ask Docker to kill and remove the container as soon as the script has been executed (otherwise you'll have a lot of exited but not removed Docker containers; you can check this by not using the--rmflag then runningdocker container liston the console),-v "${PWD}":/projectto share your current folder with a folder called/projectin the Docker container (use${PWD}if you are on Linux, use%CD%if you are on DOS),-w /projectto tell Docker that the current directory, in the container, will be the/projectfolder- then
jakzal/phpqawhich is the name of the Docker image to use (you can also specify a version likepython:3.9.18if needed; see https://hub.docker.com/_/python/tags)
Composer unused
Composer unused will try to understand which packages are mentioned in your composer.json file and, perhaps, not used anymore.
By running docker run -it --rm -v "${PWD}":/project -w /project jakzal/phpqa composer-unused in your project, you'll get something like this:

So, the tool detects that I'm referencing spatie/laravel-db-snapshots in my composer.json file but, in my codebase, the tool (in fact, the namespace added by the tool) isn't used at all so, yes, probably, I can remove that dependency.
Caution
Such a tool can produce false positive; just make some checks before removing the dependency. The best solution here is, of course, to have plenty of unit tests so you can run them before and after the change and see if your code still works as expected.
Composer normalize
Composer normalize will reorder your composer.json file to match best practices.
As you know, in a JSON file, there is no order so you can define your properties in any order. For instance:
{ "name": "ergebnis/composer-normalize", "description": "Provides a composer plugin for normalizing composer.json.", "license": "MIT", "type": "composer-plugin"}This is a package definition file (composer.json) that describes a plugin for Composer, which is PHP's package manager. The plugin's job is to automatically organize and standardize the formatting of composer.json files. It's licensed under MIT, meaning it's free to use and modify.
or
{ "license": "MIT", "description": "Provides a composer plugin for normalizing composer.json.", "type": "composer-plugin", "name": "ergebnis/composer-normalize"}This is a package configuration file (composer.json) that describes a tool called composer-normalize. It's a plugin for Composer (PHP's package manager) that automatically cleans up and standardizes the format of composer.json files. The MIT license means anyone can use it freely.
or anything else. The above example is just four lines; imagine a file with a hundred lines. It's more logical, isn't it, to retrieve first the name of the tool, then a small description, the license, the type (is it a project, a library, ...) and so on and not, f.i., first the list of requirements.
Ok, so, to normalize your composer.json file, you can install the tool or, and this is the objective of this blog post, simply run docker run -it --rm -v "${PWD}":/project -w /project jakzal/phpqa composer normalize and that's all.
The result will be a rewritten composer.json file where properties are put in standard order.
Information
Add --dry-run if you just want to see what the changes will be; but do not modify any files.
PHP-Parallel-lint
As a third example, we'll see PHP-Parallel-Lint.
This tool will scan all .php files present in your codebase and ensure there is no syntax error like a missing }.
The command to run here is docker run -it --rm -v "${PWD}":/project -w /project jakzal/phpqa parallel-lint . --exclude vendor.
Think about adding exclusions like --exclude vendor so you don't scan code that isn't yours.
As you can see below, in less than two seconds, the tool has checked 823 files of my codebase. Pretty fast.
PHP-CS-FIXER
Another tool, PHP-CS-FIXER. The PHP Coding Standards Fixer (PHP CS Fixer) tool fixes your code to follow standards.
Here the command will be docker run -it --rm -v "${PWD}":/project -w /project jakzal/phpqa php-cs-fixer fix to reformat all your codebase according to the selected rulesets. If none is mentioned, PSR-12 will be the default one.
PHP_CodeSniffer
Another tool, PHP_CodeSniffer. PHP_CodeSniffer tokenizes PHP files and detects violations of a defined set of coding standards.
This time, the command will be docker run -it --rm -v "${PWD}":/project -w /project jakzal/phpqa phpcbf .
A whole host of other tools await you
As you can see, we can use a lot of tools using jakzal/phpqa in a zero-installation schema. That's really impressive. You can find a lot more tools than described in this article, just go to Available tools and see which ones can help you.
Two natural next steps once you've picked your tools: run them before committing, thanks to Git pre-commit hooks, and run them again in your CI, as described in GitLab - Running Docker-out-of-Docker in your CI.
Change PHP versions
Let's imagine your codebase is a legacy one (not written for PHP 8.3 but f.i. PHP 7.4).
An instruction like docker run -it --rm -v "${PWD}":/project -w /project jakzal/phpqa parallel-lint . --exclude vendor (as we have seen above) will scan the code with PHP 8.3 (situation end March 2024) and you can have plenty of errors since you're using a PHP 8.3x tool on a PHP 7.4x codebase.
How to solve this? Really easy in fact. As you know, by using docker run [...] jakzal/phpqa [...] you're asking Docker to use the latest version of the image and that version will change. Every time the owner of the image publishes a newer version, that latest image is updated and perhaps, in a few months, it'll be PHP 8.4 by default.
So, to solve our issue: we need to use a specific tag for PHP 7.4. And if the tools complain about your PHP settings rather than your code, see Update php.ini when using a Docker image. Simply jump on https://hub.docker.com/r/jakzal/phpqa/tags and type 7.4 in the Filter Tags area.

You'll find some tags. Now you can start docker run -it --rm -v "${PWD}":/project -w /project jakzal/phpqa:1.80-php7.4-alpine parallel-lint . --exclude vendor to run the PHP 7.4 linter.
This article is part of the code quality series:
- Markdown linter - solve formatting issue in md files
- Rector 1.0.0 🎉🎉🎉, my friend, my coach
- Docker image that provides static analysis tools for PHP
- Clean code - Linux Bash - Keep the number of function parameters as small as possible
- SQL - Formatting tool
- JSON - Online linter
- Format poorly formatted PHP code
- Python - Code Quality tools
- Git - pre-commit-hooks
- Validate your OpenAPI schema against the Belgif REST standards




