Enhance your productivity on your PHP projects
For every new projects I have to work on, I always start by adding at least 3 libraries to ease my workflow.
- PHPStan - A static analysis tool
- Psalm - An advanced static analysis tool
- Easy Coding Standard - Pack of rules for Simplify/EasyCodingStandard
They have become my best friends with PHPStorm in order to refactor every piece of code.
Why do you need Static Analysis?
At first, if you are not familiar with static analysis tools, let me explain what they are. You write PHP interfaces, classes, methods and so on. All of that code is orcherstrated to make beautifull apps. But you should know that when adding new features, you may create potential bugs. Here is where those tools come in.
Static Analysis tools are programs that analyse other codebases without actually executing it. You could find a lot of those tools online. For instance, there's a Wikipedia page listing all known projects.
They will parse all of your code and try to find potential errors thanks to types and AST.
If you're not convinced yet, here is another view on PHPStan:
How to configure PHPStan for Symfony applications
Nowadays I can't imagine developing modern PHP applications without PHPStan running on max level with lots of checks. It helps to prevent many issues during development and refactoring of the applications.
Why do you need a Code Style library?
EasyCodingStandard describes itself as "Easiest way to start using PHP CS Fixer and PHP_CodeSniffer with 0-knowledge". Those two sub-packages enables your team to create a set of style rules to follow during the life of the project.
Even if you're working alone, you can take advantage of such tool. Think about projects you left aside for a few month.
Now, how to automatically use it?
You will only need those two commands to run:
vendor/bin/phpstan analyse src --level=max
vendor/bin/ecs check src --fix
Step 1: Make it simple
app@tests: app@lint-php app@quality-tests app@lint-php: vendor/bin/ecs check src app@lint-git-diff: vendor/bin/ecs check $$(git diff --name-only --diff-filter=ACMRTUXB HEAD~..HEAD -- '*.php') app@lint-php-fix: vendor/bin/ecs check src tests --fix app@quality-tests: app@php-analysis app@php-analysis: vendor/bin/phpstan analyse src --level=max vendor/bin/psalm
You could also make it works with composer scripts and any other tool you're familiar with.
make app@tests to be able to spot error prone php code you wrote.
Or make use of GrumPHP to add pre-commit hooks if you want to enforce rules before each commit.
You could also follow the next part about Gitlab-CI.
Step 2: Every push should be follow by a CI validation
But to be sure to really automate all the things, write a
.gitlab-ci.yml file. It will be your best friend before merging Merge Requests. :D
image: name: 'your-super-duper-php-docker-image' # Or any Docker image entrypoint: [''] before_script: - composer install --prefer-dist --no-progress --no-suggest --no-interaction variables: CI_DEBUG_TRACE: 'false' GIT_SSL_NO_VERIFY: 'true' tests: tags: - 'docker' script: - composer validate --no-check-publish - php bin/console security:check composer.lock --end-point=https://security.symfony.com/check_lock # If you're working on a Symfony project - vendor/bin/ecs check $(git diff --name-only --diff-filter=ACMRTUXB HEAD~..HEAD -- '*.php') - php vendor/bin/phpstan analyse src --level=max
If your CI Jobs are reds, you should block any merge from performing before a new validation.
I prefer to check code style only for the git diff for old projects with a lot of code smells. It also make it easier to review your merge requests as you won't modify unrelated files.
I don't enforce Psalm rules yet. I just started to work with it on newer projects. However, it has a greater understanding of PHPDoc, a specific set of annotation, templating, assertions and great php projects refactoring tools
With this toolchain, you're ready to work fast but with a nice seatbelt! Furthermore, you could add smoke tests with PHPUnit to your API/Website/CLI project to start with baby steps in the Unit Tests world. 💪
Honestly, I would love to know what are the equivalent most use tools for