Trimming whitespace from Drupal form submissions using an HTTP middleware

Matt Glaman
2 min readJan 10, 2023

Leading and trailing whitespaces. The bane of normalized data everywhere. It seems like a constant task that needs to be performed on incoming user data. When working with Laravel, I use the TrimStrings middleware. Calls PHP's built-in trim function on all string values for the request query and input values – including JSON! While working on my project WhiskeyDex, I noticed how mobile device keyboards always add trailing whitespace when using the autocomplete functionality. This, in turn, meant user-created data will end up with trailing whitespaces. I started to just quick-fix in the single instance and realized it should be solved once and for all.

Drupal does not provide as many developer-friendly tools as Laravel, so I needed to recreate my version of the TrimStrings middleware. It's fairly simple, requiring one class and its service registration. Note: the following code is for PHP 8.1.

In your module, create a src/StackMiddleware/TrimMiddleware.php file with the following:

<?php

declare(strict_types=1);

namespace Drupal\whiskeydex\StackMiddleware;

use Symfony\Component\HttpFoundation\InputBag;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpKernelInterface;

final class TrimMiddleware implements HttpKernelInterface {

public function __construct(
private readonly HttpKernelInterface $app
) {
}

public function handle(
Request $request,
int $type = self::MAIN_REQUEST,
bool $catch = TRUE): Response {
$this->trimBag($request->query);
$this->trimBag($request->request);
return $this->app->handle($request);
}

private function trimBag(InputBag $bag): void {
$bag->replace($this->trimArray($bag->all()));
}

private function trimArray(array $array): array {
return array_map(
function ($value) {
if (is_array($value)) {
return $this->trimArray($value);
}
return is_string($value) ? trim($value) : $value;
},
$array
);
}

}

The real work is in trimArray, which iterates through the array, and any nested ones, returning trimmed strings.

Then register the service in your module’s services.yml:

services:
http_middleware.trim:
class: Drupal\whiskeydex\StackMiddleware\TrimMiddleware
arguments: ['@kernel']
tags:
- { name: http_middleware }

Here is a link to a gist of the code as well: https://gist.github.com/mglaman/4533051f0ec50ebd698bbde93c1ac79b

--

--

Matt Glaman

PHP software engineer, open source contributor, and speaker