The PSR-12 coding standard replaces the previous PSR-2 standard. It takes new PHP features into account.

PSR-12 additionally takes the following constructs into account, compared to PSR-2:

  • Traits


  • Underscores to indicate visibility are now forbidden.

What’s changed in PSR-12 in comparison to PSR-2

2.5 Keywords and types

Short form of type keywords MUST be used i.e. bool instead of boolean, int instead of integer etc.

3. Declare Statements, Namespace, and Import Statements

In PSR-2 the ordering of statements was not set.

The order is now strictly defined:

  • Opening <?php tag.

By default, variables will be split by space characters. This is not what you want if you have a message that contains spaces for example.

To prevent this, the variable may be surrounded by quotation marks. If you’re using the exec form in the ENTRYPOINT. quotation marks can be escaped with backslashes.

Let's see an example:


Takes two variables (message and version) and prints them.

#!/usr/bin/env sh
set -euo pipefail
# Parameters:
# $1: Message
# $2: Version
printf 'Message is: %s\n' "${1}"
printf 'Version is: %s\n' "${2}"


# To run: # docker build . -f Dockerfile -t docker-entrypoint-test && docker run…

How to use SonarScanner CLI.

This is an example of how you can use the SonarScanner CLI. For example, if you want to scan a PHP application. There are also alternatives: Gradle & Maven.

Create a file called sonar-project.properties inside of your repository root. As stated in the SonarQube GitLab CI documentation.

# SonarQube server
# sonar.host.url & sonar.login are set by the Scanner CLI.
# See https://docs.sonarqube.org/latest/analysis/gitlab-cicd/.

# Project settings.
sonar.projectName=My project
sonar.projectDescription=My new interesting project.

# Scan settings.
# Define the directories that should be scanned. Comma separated.
sonar.test.inclusions=**/*Test.php sonar.php.coverage.reportPaths=./coverage/lcov.info sonar.php.file.suffixes=php sonar.sourceEncoding=UTF-8 sonar.exclusions=,**/coverage/**…

Testing if using Mutagen improves performance in comparison to NFS volume mounts. Comparing MacOS Docker performance with Linux.

Image for post
Image for post

Performance improvement by using Mutagen compared to NFS volume mounts: ~25%. Mutagen causes high CPU usage when using multiple syncs. Development experience not ideal due to delays until files are synced. Issues with intentional mass file changes being prevented by Mutagen safety mechanisms.

TL;DR; when using PHP / Drupal
xDebug increased Drupal response times by about 5–6x. I’ve added an environment variable that allows disabling it on Docker run if I don’t need to debug.


I’ve been using Docker for local…

Image for post
Image for post
Licensed under Creative Commons.


The Symfony translation component allows you to extract translations from your PHP codebase & Twig templates into the translation file format of your liking, for example .po files.

The documentation describes it like this:

The most time-consuming tasks when translating an application is to extract all the template contents to be translated and to keep all the translation files in sync. Symfony includes a command called translation:update that helps you with these tasks.

But what if not all my translations are hardcoded in code or templates, and some - or all - are dynamic? …

Image for post
Image for post
Composer logo. Licensed under the MIT license.

How packages.drupal.org sets drupal/core version constraints that prevent updating to Drupal 9.

I went about to update a Drupal 8 project to Drupal 9. As preparation, I updated all Composer dependencies to their latest major versions and Drupal to the latest version of Drupal 8.

I quickly noticed that a few modules didn’t have a version out that supports Drupal 9 yet. Luckily all of them already had patches ready to fix this. Easy, just apply the patches inside the composer.json’s extra: { patches: { } } block (assuming you’re using the cweagans/composer-patches library). And done. Sadly this does not…

Orlando Thöny

PHP Software Engineer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store