PHP und dotenv-Dateien
Dotenv-Dateien sind mittlerweile ein weit verbreitetes Format zur Anpassung einer Anwendung an eine bestimmte Umgebung. Sie sind eine Untermenge der Bourne-Shell-Syntax, die eine Reihe von Variablen definiert. Sie bieten keine komplexe Strukturierung wie INI- oder gar YAML-/TOML-Dateien, aber das ist oft auch garnicht nötig.
Hier ein kleines Beispiel:
SERVER="tau"
PATH="/opt/bbs"
REMOTE="${SERVER}:${PATH}"
Im Gegensatz zu anderen Dateiformaten lassen sich dotenv-Dateien ohne zusätzliche Programme oder umständliche Verarbeitung mit sed ganz leicht in Shell-Skripten verwenden, z.B. in Git-Hooks; außerdem können wie in der Shell Variablen auch den Wert anderer Variablen enthalten, wie im obigen Beispiel zu sehen, was mit INI-, YAML- oder TOML-Dateien nicht möglich ist.
In meinem vorherigen Post habe ich ein Projekt vorgestellt, das ebensolche Dateien nutzt. Teil des Projektes ist ein PHP-basiertes Frontend, welches mittlerweile die vom in Python implemeniterten Backend verwendete dotenv-Datei ebenfalls nutzt.
Composer installieren
Um phpdotenv als Abhängigkeit zu installieren, wird composer verwendet, der Quasi-Standard Paketmanager für PHP. Dieser muss, falls nicht bereits geschehen, installiert werden:
# macOS
brew install composer
# ArchLinux
sudo pacman -S composer
# Debian
sudo apt install composer
phpdotenv via Composer installieren
Jetzt kann Composer angewiesen werden, phpdotenv als Abhängigkeit zum Projekt hinzuzufügen. Falls nötig, wird dafür die composer.json-Datei erstellt, und phpdotenv wird unter vendor/ installiert:
composer require vlucas/phpdotenv
dotenv in PHP laden
Composer lädt für uns automatisch alle notwendigen Dateien für verwendete Funktionen, und erspart unzählige require()-Anweisungen. Es muss nur am Anfang des PHP die Datei vendor/autoload.php eingebunden werden:
require_once("vendor/autoload.php");
Jetzt kann die dotenv-Datei aus dem aktuellen Verzeichnis geladen werden (oder alternativ z.B. aus dem übergeordneten Verzeichnis: __DIR__."/.."):
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
Wenn kein Verlass darauf sein kann, dass eine .env-Datei existiert, sollte safeLoad() genutzt werden:
$dotenv->safeLoad();
PHP und Umgebungsvariablen
Die Standardeinstellung der variables-order-Option in der php.ini ist "GPCS", und verhindert dass $_ENV die üblichen Umgebungsvariablen enthält.
In unserem Fall enthält $_ENV also nur die aus der dotenv-Datei geladenen Werte. Alle anderen Umgebungsvariablen sind nur über getenv() verfügbar. Wenn variables-order auf "EGPCS" gesetzt wird, enthält $_ENV auch diese. Allerdings ist davon abzuraten sich darauf zu verlassen, da wie gesagt erst eine PHP-Option auf einen nicht-Standardwert gesetzt werden muss.
Auf die Variable zugreifen
Jetzt kann auf die Variablen via $_ENV zugegriffen werden:
do_stuff($_ENV["REMOTE"]);
Das Problem mit getenv()
Wie im README von phpdotenv erläutert, ist getenv() nicht thread safe. Deshalb sollte auf die geladenen Umgebungsvariablen nur via $_ENV oder $_SERVER zugegriffen werden, nicht via getenv().