Most Common Coding Standard Mistakes
The same handful of mistakes turn up in project after project, surprisingly consistently. This chapter is a quick-reference list of the ones that show up most, and why each one is worth catching rather than waving off as a nitpick.
1. The Usual Suspects
The list barely changes from one codebase to the next:
- 4 spaces used instead of 2.
- Tabs used for indentation instead of spaces.
- The old
array()syntax kept around instead of[]. - A missing trailing comma in a multi-line array.
- A namespace or class name that doesn't match its file path.
- A service class built without dependency injection.
- Text that needs translation written as a hard-coded string.
- An unnecessary
|rawfilter used inside a Twig template. once()left out of a JavaScript behavior.- A deprecated Drupal API still called from new code.
2. Old Array Syntax
The single most common one: array() still turning up in code that should be using the short array syntax everywhere.
// ❌ Old syntax: array().
$items = array(
'one',
'two',
);
// ✅ Current syntax: short array literal.
$items = [
'one',
'two',
];Looked at on its own, the difference is trivial. Repeated hundreds of times across a codebase of thousands of lines, it becomes a real, if small, maintenance cost — and it's usually a sign the rest of the file hasn't been touched by phpcbf in a while either.
3. Skipped Dependency Injection
A static \Drupal::service() call reaching into the container from inside a method, instead of the service arriving through the constructor, is common enough to be worth calling out again on its own — see the architecture chapter for the full version of this rule and why it matters for testing.
4. Untranslated Strings
Text meant for the end user, written directly into a template or a render array instead of passed through t() or the |t filter, is easy to miss in a quick review because the page still looks correct — right up until someone tries to translate the site.
// ❌ Incorrect: never reaches the translation system.
$build['#markup'] = 'No products found.';
// ✅ Correct: passed through t().
$build['#markup'] = $this->t('No products found.');5. Why These Add Up
None of these individually breaks anything. What changes is how a codebase feels to work in as it grows: in one that consistently follows the standards, a new developer can be productive within a week; in one that doesn't, they spend that same week asking why things were done a particular way, with no good answer waiting for them. Tools like PHP_CodeSniffer, PHPStan, ESLint, and Stylelint exist precisely so none of this has to be caught by memory — set up once, they catch the great majority of it automatically.