malte70.blog()

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().