2 minutes
Use dotenv to configure a Zend Expressive application
This article is part of my #100DaysOfCode and #100DaysOfBlogging challenge. R1D6
[The Twelve-Factor App] requires strict separation of config from code.
Taken from factor three of The Twelve-Factor App.
Today I am studying about how to achieve this requirement making usage of phpdotenv in a Zend Expressive context.
I will not go into details on and advantages of this concept. A leave that up to other resources.
phpdotenv
This package
Loads environment variables from
.env
togetenv()
,$_ENV
and$_SERVER
automagically.
It has a clean setup and interface. To load an .env
file use
$dotenv = Dotenv\Dotenv::create(__DIR__);
$dotenv->load();
Then you can access it via
$s3Bucket = getenv('S3_BUCKET');
$s3Bucket = $_ENV['S3_BUCKET'];
$s3Bucket = $_SERVER['S3_BUCKET'];
The documentation mentions also the possibility to access variable through the request class. This is out-of-scope of this blog entry, since I want to access env vars only in configuration files.
Install phpdotenv
I install the package via Composer.
composer require vlucas/phpdotenv
Create a dotenv file
Next, I create a .env
file.
DOCTRINE_CONNECTION_HOST="localhost"
DOCTRINE_CONNECTION_PORT="3306"
DOCTRINE_CONNECTION_USER="db_user"
DOCTRINE_CONNECTION_PASSWORD="my-53cr37"
DOCTRINE_CONNECTION_DBNAME="database"
DOCTRINE_CONNECTION_charset="utf8mb4"
Load dotenv
Now phpdotenv
needs to be put to work and do its magic. In my index.php
I add the following two lines right after requiring the composer autoload file.
$dotenv = Dotenv\Dotenv::create(__DIR__);
$dotenv->load();
Load configuration from dotenv
My configuration file with the database is updated, to use the env vars now available through getenv()
.
<?php
declare(strict_types = 1);
return [
'doctrine' => [
'connection' => [
'orm_default' => [
'params' => [
'host' => getenv('DOCTRINE_CONNECTION_HOST'),
'port' => getenv('DOCTRINE_CONNECTION_PORT'),
'user' => getenv('DOCTRINE_CONNECTION_USER'),
'password' => getenv('DOCTRINE_CONNECTION_PASSWORD'),
'dbname' => getenv('DOCTRINE_CONNECTION_DBNAME'),
'charset' => getenv('DOCTRINE_CONNECTION_CHARSET'),
],
],
],
],
];
Goal accomplished
A quick check on my API confirms that the env vars are utilized correctly. 👍