Create Custom Environment Variable Processor in Symfony 8

Create Custom Environment Variable Processor in Symfony 8

Symfony allows environment variables to be transformed before they are injected into configuration values. This is handled by environment variable processors, which are especially useful when configuration values require preprocessing instead of raw strings. The DependencyInjection component ships with several built-in processors, but there are scenarios where a custom processor is required. This tutorial shows how to create custom environment variable processor in Symfony 8 application.

Let's say environment variable stores a duration using a short notation such as 30m or 1h, while the application expects the value as an integer number of seconds.

Example environment configuration:

.env

SESSION_TTL=30m

The processor can be referenced using a custom prefix. In this example, the prefix is duration.

config/services.yaml

parameters:
    session_ttl: '%env(duration:SESSION_TTL)%'

Custom processors must implement EnvVarProcessorInterface. This interface defines two required methods:

  • getProvidedTypes - declares supported prefixes and their return types.
  • getEnv - transforms the environment variable value.

In the following code, the processor extracts the last character of the environment variable value to determine the unit and converts the numeric portion into seconds.

src/DependencyInjection/DurationEnvVarProcessor.php

<?php

namespace App\DependencyInjection;

use Closure;
use Symfony\Component\DependencyInjection\EnvVarProcessorInterface;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;

class DurationEnvVarProcessor implements EnvVarProcessorInterface
{
    public static function getProvidedTypes(): array
    {
        return ['duration' => 'string'];
    }

    public function getEnv(string $prefix, string $name, Closure $getEnv): string
    {
        $env = $getEnv($name);
        $unit = $env[-1] ?? null;

        return match ($unit) {
            's' => (int) $env,
            'm' => (int) $env * 60,
            'h' => (int) $env * 3600,
            default => throw new RuntimeException(sprintf('Invalid unit "%s".', $unit)),
        };
    }
}

Once registered, the parameter can be accessed anywhere parameters are available. The following controller displays the resolved duration value.

src/Controller/TestController.php

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

class TestController extends AbstractController
{
    #[Route('/')]
    public function index(): Response
    {
        return new Response($this->getParameter('session_ttl'));
    }
}

With SESSION_TTL=30m, the response will contain 1800.

Leave a Comment

Cancel reply

Your email address will not be published.