Centralize Environment Config into a Service

Table of Contents

📖 2 minutes read

Scattering env() calls across your codebase creates hidden coupling and makes testing painful. Here’s a better pattern: centralize related configuration into a dedicated service.

The Problem

When you need external service credentials, it’s tempting to reach for env() wherever you need them:

class ReportUploader
{
    public function upload($file)
    {
        $host = env('CLIENT_SFTP_HOST');
        $user = env('CLIENT_SFTP_USERNAME');
        $pass = env('CLIENT_SFTP_PASSWORD');
        
        $this->sftpClient->connect($host, $user, $pass);
        // ...
    }
}

This works, but now your service class is tightly coupled to specific environment variable names. Change a variable name? Hunt down every env() call. Mock config for tests? Good luck.

The Fix

Create a settings service that acts as a single source of truth:

class ClientSettingsService
{
    public function getSftpHost(): string
    {
        return config('clients.sftp.host');
    }

    public function getSftpUsername(): string
    {
        return config('clients.sftp.username');
    }

    public function getSftpPassword(): string
    {
        return config('clients.sftp.password');
    }
}

Now inject the service instead of calling env() directly:

class ReportUploader
{
    public function __construct(
        private ClientSettingsService $settings
    ) {}

    public function upload($file)
    {
        $host = $this->settings->getSftpHost();
        $user = $this->settings->getSftpUsername();
        $pass = $this->settings->getSftpPassword();
        
        $this->sftpClient->connect($host, $user, $pass);
        // ...
    }
}

Benefits

  • Centralized changes: Rename a config key? Update one service method.
  • Easy testing: Mock the service, not individual env() calls.
  • Type safety: Explicit return types catch config issues at compile time.
  • Domain clarity: $settings->getSftpHost() is more readable than env('CLIENT_SFTP_HOST').

If you’re reaching for env() in a service class, stop. Create a settings service first.

Daryle De Silva

VP of Technology

11+ years building and scaling web applications. Writing about what I learn in the trenches.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *