Jump to content

Using .env files with ProcessWire


FireWire
 Share

Recommended Posts

Hello!

I use .env files on every ProcessWire project to manage environment-specific configurations and settings. I've built a ProcessWire specific utility that makes using .env files a breeze. This post isn't intended to debate .env vs. config.php, use what you're comfortable with and prefer. That said, here are a few benefits to using .env files that may make it worth considering:

  • Native support on web servers, including Apache, they are not served via http request by default
  • True environment based secrets and settings management
  • A standard file widely used and accepted as the method for managing secrets and sensitive values
  • Able to store any value whether sensitive or not and access them globally

Building a dedicated solution came from a discussion here on the forums where I threw together a rough implementation that needed little polish for real world use. It makes use of phpdotenv.

This utility delivers the following:

  • Easy use of and access to .env variables
  • Caching the parsed .env for performance. This is a significant part of this utility and addresses a known need
  • Automatic .env change recognition and re-caching
  • Utilities to make working with environment variables feel ProcessWire native and a few extra nifty things

What it isn't:

  • A module. It's not possible to make a module for this need because the information kept in a .env file needs to be available before ProcessWire boots.

Adding this to a new or existing project is very easy. It's designed to implement quickly and use immediately in your projects. Full documentation is provided in the Github repository.

Here are a few examples of using this tool:

<?php namespace ProcessWire;

use Env\Env;

if(!defined("PROCESSWIRE")) die();

$env = Env::load(__DIR__ . '/../');

// Make env available throughout the application
$config->env = $env;

$config->dbName = $env->get('DB_NAME');
$config->dbUser = $env->get('DB_USER');
$config->dbPass = $env->get('DB_PASS');

// Env::get() takes a second argument that is the fallback value if for any reason DEBUG doesn't exist 
$config->debug = $env->get('DEBUG', false);

// Conditional values. By default, if the condition is falsey, Env::if() returns null   
$config->adminEmail = $env->if('APP_ENV', 'production', 'you@youremail.com');

// A fourth argument will be returned if condition is false, truthy/falsey output can be env var names or specific values
$config->adminEmail = $env->if('APP_ENV', 'production', 'ADMIN_EMAIL', 'you@youremail.com');

// Conversely, you can also check if a condition is not met.
$config->adminEmail = $env->ifNot('APP_ENV', 'development', 'ADMIN_EMAIL');

// Use one env value to set multiple config properties
$config->advanced = $env->if('APP_ENV', 'production', false, 'ENABLE_ADVANCED'); // Never in production, change locally in env as needed
$config->adminEmail = $env->ifNot('APP_ENV', 'development', 'ADMIN_EMAIL'); // Never send an email in dev, always on staging/production

These helper methods make is very straightforward to implement a dynamic config file. This can be useful for using secure .env values while retaining the ability to commit and upload some types of changes to your config.php file without needing to touch .env values on the server.

You can also use Env::pushToConfig(). As long as you use the "screaming snake case" naming convention for your environment variable names, type and value recognition are handled automatically.

<?php

$env->pushToConfig($config, [
    'usePageClasses' => true,
    'templateCompile' => 'TEMPLATE_COMPILE',
    'debug' => ['DEBUG', false], // Fallback to false
    'advanced' => $env->if('APP_ENV', 'production', false, 'ENABLE_ADVANCED'),
    'adminEmail' => $env->ifNot('APP_ENV', 'development', 'ADMIN_EMAIL'),
    'httpHosts' => [
        'something.com',
      	'staging.something.com',
        'something.ddev.site'
    ],
]);

Using Env in your application files and templates can be very useful. In the above example we assigned the Env object to $config->env. This lets you access your .env variables globally and use some helpful methods.

<?php if ($config->env->eq('APP_ENV', 'development')): ?>
  <script src="/some/development/stuff.js"></script>
<?php endif ?>

<?php
if (!$config->env->exists('GOOGLE_API_KEY')) {
  $wire->error('A Google API key could not be loaded from the environment file.');
}

try {
  // Do something that could fail	
} catch (Exception $e) {
    $message = $config->env->if('APP_ENV', 'production', 'Oh no. Friendly message here', $e->getMessage());
}

This utility also automatically casts 'true' and 'false' values in .env files to booleans, and casts numbers to integers. It also includes several configuration options.

I have been using this tool in production and have been happy with it. Maybe you might find it helpful in your projects as well. If you like it, throw a star on the repo. If you run into any bugs, file an issue on Github. I may publish it as a composer package at some point.

Env utility for ProcessWIre on Github.

  • Like 6
  • Thanks 2
Link to comment
Share on other sites

@elabx Same here, once I stumbled across that Github issue with performance I wanted to implement caching. There were a couple of places I needed to access env variables elswhere in my code, so this all grew out of some real world experience.

I have my env folder in the root directory. The folders in the repo come with .htaccess files already placed which block access to any assets via http request, no need to make any changes to the ProcessWire .htaccess file. This can be used without any changes to ProcessWire itself.

Link to comment
Share on other sites

  On 3/3/2025 at 6:15 PM, elabx said:

hadn't noticed the .htaccess files

Expand  

@elabx Those are really just a matter of being thorough with security. Another answer to your question about where to put the env folder is anywhere you want really. As long as you update your composer.json file so the namespace resolves to the location that folder you can keep it anywhere.

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...