Actualmente se considera que mantener los parámetros sensibles de configuración, como los datos de conexión a base de datos, la key de una API, etc.. en un fichero de configuración que va a ser leído por la aplicación, como algo inseguro. El camino más fiable para poder disponer de esta información será través de las variables de entorno. El propio autor menciona la sección relativa a la configuración de The Twelve Factor App, una metodología ampliamente aceptada para el desarrollo de aplicaciones. El fichero finalmente se puede filtrar de alguna manera, mientras que las variables de entorno al estar solo presentes en la sesión de la ejecución, no. El servidor se puede parametrizar para que estas no sean propagadas arbitrariamente entre los subprocesos que se deriven del principal.

Para no tener que preocuparnos de esta configuración en los entornos de desarrollo, la librería PHP dotenv se encargará de leer un fichero donde recogerá los valores de estas variables y las inyectará en los arrays $_ENV y $_SERVER también las hará accesibles a través de la function getenv(). De esa manera podremos acceder a estos valores como en producción.

Uso

La librería PHP dotenv es de las más utilizadas, se puede incluir en cualquier proyecto mediante Composer.

1
php composer.phar require vlucas/phpdotenv

Tras su instalación necesitaremos crear un archivo .env donde almacenaremos los valores que vamos a consultar a través de las variables de entorno. El autor recomienda incluir el archivo .env en .gitignore, ignorarlo en el control de versiones que estemos utilizando. Para almacenar se puede generar un archivo modelo, lo más habitual es añadirle la extensión .dist, el autor recomienda .example, pero es más común el uso de .dist . Así que generaremos un archivo .env.dist con las variables necesarias, pero, con valores falsos, de manera que, un desarrollador las pueda copiar a un fichero .env y configurar ahí los valores reales correspondientes a su entorno.

La sintaxis es sencilla, VARIABLE_STRING=”string”, VARIABLE_INT=99 o VARIABLE_INT=”99”. Admite comentarios precedidos por #.

1
2
3
4
5
6
# .env.dist
DB_USER="falseUsername"
DB_PASSWD="falsepass"
DB_NAME="dbname"
DB_HOST="localhost"
DB_PORT=3306

Una vez copiado el fichero a .env y cambiado los datos a los reales, cargamos los valores haciendo una instancia del objeto Dotenv, usando como parámetro el directorio del fichero .env. Posteriormente llamamos a la función load(), para que incluya las variables en memoria.

1
2
3
4
5
6
7
8
9
10
<?php

require '../vendor/autoload.php';

$dotenv = new Dotenv\Dotenv(__DIR__);
$dotenv->load();

echo getenv('DB_USER') . PHP_EOL;
echo $_ENV['DB_USER'] . PHP_EOL;
echo $_SERVER['DB_USER'] . PHP_EOL;

Mediante cualquiera de los tres métodos arriba descritos, tras el load(), podremos obtener su valor. la función getenv() o las globales $_ENV y $_SERVER.

Variables anidadas.

Podemos hacer declaraciones de variables que usan variables anteriormente definidas. Se referencian con ${…}

1
2
3
BASE_DIR="/var/www/project"
CACHE_DIR="${BASE_DIR}/cache"
TMP_DIR="${BASE_DIR}/tmp"

Requiriendo variables.

Se puede requerir que exista una o varias variables de entorno para la ejecución del programa, se invoca la función required() usando como parámetro un string con el nombre de la variable requerida o un array de strings con multiples variables. En caso de no estar definidas el sistema devolverá una Runtime Exception.

1
2
3
4
5
6
7
8
9
<?php

require '../vendor/autoload.php';

$dotenv = new Dotenv\Dotenv(__DIR__);
$dotenv->load();

$dotenv->required('DATABASE_DSN')->notEmpty();
$dotenv->required(['DB_HOST', 'DB_NAME', 'DB_USER', 'DB_PASSWD']);

En el primer ejemplo, tras el require se puede ver la llamada a la función notEmpty(), que asegurará que la variable además contenga valor. Tendremos que añadir la variable al archivo .env y darle un valor para evitar la Exception.

También se puede comprobar que la variable sea integer required(‘DB_PORT’)->isInteger() o que contenga alguno de multiples valores definidos required(‘DB_HOST’)->allowedValues([“val1”, “val2”]).

Una herramienta muy versátil que hará más portable el proyecto al poder ser inicializado rápidamente por cualquier desarrollador de una manera standard… Últimamente estoy más escaso de tiempo que nunca, pero aprendiendo un montón de cosas nuevas, espero poder transmitir algunas de ellas por aquí, herramientas, webs, standares… Camino a la APIficación ;) ..