DotEnv e la Gestione delle Variabili d'Ambiente

0
1317

A partire dalla nuova versione 5, Laravel usa DotEnv per la gestione di alcuni valori dei file di configurazione.

Cosa? Non ci hai fatto caso?

Guarda qui: questa di seguito è una sezione del file di configurazione del database.

‘mysql’ => [
‘driver’ => ‘mysql’,
‘host’ => env(‘DB_HOST’, ‘localhost’),
‘database’ => env(‘DB_DATABASE’, ‘forge’),
‘username’ => env(‘DB_USERNAME’, ‘forge’),
‘password’ => env(‘DB_PASSWORD’, ”),
‘charset’ => ‘utf8’,
‘collation’ => ‘utf8_unicode_ci’,
‘prefix’ => ”,
‘strict’ => false,
],

Ti coglie di sorpresa? Non ti preoccupare, un passo alla volta.

DotEnv?

DotEnv è un package, originariamente scritto in Ruby e poi “tradotto” in PHP da Vance Lucas. In parole povere, permette di recuperare, tramite una funzione getenv(), dei valori di configurazione memorizzati in un file .env.

Dovresti avere, infatti, tale file nella cartella principale del tuo progetto Laravel.

Ecco come appare, indicativamente:

APP_ENV=local
APP_DEBUG=true
APP_KEY=EhkHUlNhvTUcaFhJBRBin7TVla91CKaj

DB_HOST=localhost
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret

CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync

MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null

Ci hai già fatto caso? Guarda questa linea del file di configurazione:

‘database’ => env(‘DB_DATABASE’, ‘forge’),

e guarda questa linea del file .env:

DB_DATABASE=homestead

Esatto. In poche parole, Laravel usa le funzionalità di DotEnv per prelevare da un file di configurazione esterno dei valori ed usarli al posto di scriverli direttamente nei file in config, nel codice PHP vero e proprio.

Ok, ma perché?

I file di configurazione sono ottimi per evitare di scrivere nel codice vero e proprio dei valori (a volte anche dati sensibili).

Ora, una buona regola (base della metodologia twelve-factor) è di sistemare i valori di configurazione “mutevoli” in un file presente solo nell’ambiente di lavoro a cui fa riferimento, evitando di includere tale file nel codice vero e proprio dell’applicazione (e nel repository che creereai di conseguenza).

Questi valori mutevoli in base all’ambiente in cui ci si trova possono essere dei più vari:

  • il database di test in locale, e quello di produzione, che avranno credenziali diverse;
  • il sistema di cache, se in ambiente di sviluppo usi un classico insieme di file ma in produzione scegli Redis;

e così via.

Se ci pensi, il file di configurazione del database (config/database.php) va sempre messo sotto controllo di versione. Il file .env, invece, no!

Il vantaggio è quindi il seguente: tramite DotEnv la codebase rimane praticamente identica. Il file .env viene escluso dal repository proprio perché verrà creato di volta in volta per ogni deploy.

Inoltre, con un package del genere, puoi risparmiarti anche l’eventuale necessità di dover creare delle variabili d’ambiente su Apache, Nginx e così via.

Installazione ed Uso Base

Installare DotEnv è semplice, basta il comando Composer

composer require vlucas/phpdotenv

una volta installato, ci si può cominciare subito a lavorare creando un file .env vuoto.

Nota: mi raccomando, ricorda di aggiungere il file .env a quelli presenti in .gitignore.

Nota 2: ricorda anche che l’installazione NON è necessaria se stai lavorando con Laravel. Questo articolo serve soprattutto a capire come funziona il package, anche se già integrato in Laravel.

Una volta aperto il file .env puoi specificare al suo interno le variabili di cui hai bisogno seguendo questo formato:

S3_BUCKET=devbucket
SECRET_KEY=abc123

// e così via…

A questo punto, il file di configurazione viene caricato tramite una singola istruzione…

Dotenv::load(DIR);

… e da questo momento in poi, la seguente sintassi funziona senza problemi:

‘mysql’ => [
‘driver’ => ‘mysql’,
‘host’ => env(‘DB_HOST’, ‘localhost’),
‘database’ => env(‘DB_DATABASE’, ‘forge’),
‘username’ => env(‘DB_USERNAME’, ‘forge’),
‘password’ => env(‘DB_PASSWORD’, ”),
‘charset’ => ‘utf8’,
‘collation’ => ‘utf8_unicode_ci’,
‘prefix’ => ”,
‘strict’ => false,
],

Rieccoci al nostro esempio visto prima. Ora sappiamo di preciso cosa succede.

Il valore di host viene preso dal file .env. Il metodo env si occupa di prelevare tale valore dal file in questione. La chiave cercata è DB_HOST, il che vuol dire che l’elemento cercato sarà:

DB_HOST:hostname

il secondo parametro della funzione, invece, specifica un eventuale valore di default, da ritornare qualora l’elemento non venga trovato nel file .env.

In definitiva, questa riga

‘host’ => env(‘DB_HOST’, ‘localhost’),

si legge così: “per l’elemento “host” cerca nel file .env all’indice DB_HOST. Se non trovi tale voce, usa il valore localhost“.

Nota: il package DotEnv in realtà usa la funzione getenv. env è framework-specific.

Valori Obbligatori e Valori Ammessi

DotEnv permette di specificare un insieme di valori da dover necessariamente inserire nel file .env.

// chiave singola
Dotenv::required(‘DATABASE_DSN’);

// array di chiavi
Dotenv::required(array(‘DB_HOST’, ‘DB_NAME’, ‘DB_USER’, ‘DB_PASS’));

A partire da questo momento, sul file .env ci dovranno essere le corrispondenti opzioni con un valore impostato. In caso contrario, il sistema si occuperà di lanciare un’eccezione di tipo RuntimeException.

Questione di Best Practice

Prima di concludere questo veloce excursus su DotEnv, due note.

  • è buona norma inserire un file .env.example nella codebase, in modo tale che un nuovo programmatore possa facilmente copiarla in .env, sostituire i valori necessari ed iniziare a lavorare;
  • per una questione di performance, in produzione sarebbe meglio impostare direttamente i valori nei file di configurazione di Laravel. DotEnv è infatti adatto soprattutto per gli ambienti di sviluppo e testing. Nulla ti vieta di usarlo anche in produzione, ma non ti conviene molto.