eval()
Die Funktion eval() in PHP wertet zur Laufzeit einen string als PHP-Code aus. Sie ist nützlich, wenn PHP-Code dynamisch ausgeführt werden muss.
Einführung in die eval()-Funktion
Die Funktion eval() wertet einen string als PHP-Code aus und führt ihn zur Laufzeit aus — genau in dem Moment, in dem das Skript die eval()-Anweisung erreicht. Anstatt Code zu schreiben, den der PHP-Parser im Voraus kompiliert, übergeben Sie eval() einen string, der on-the-fly kompiliert und ausgeführt wird.
Das macht eval() zu einem der mächtigsten — und gefährlichsten — Sprachkonstrukte. Diese Seite behandelt die Syntax, den Rückgabewert, die seltenen Fälle, in denen die Funktion wirklich sinnvoll ist, die Sicherheitsrisiken, die sie zum letzten Ausweg machen, und die sichereren Alternativen, die Sie vorrangig in Betracht ziehen sollten.
eval()ist ein Sprachkonstrukt, keine reguläre Funktion. Sie können es nicht indirekt über einen variablen Funktionsnamen aufrufen oder an Callback-Funktionen übergeben.
Syntax
eval(string $code): mixedDas einzige Argument ist ein string mit PHP-Code. Einige Regeln sind wichtig:
- Fügen Sie kein öffnendes
<?php-Tag ein. Der string wird bereits als PHP-Quellcode behandelt, sodass das Hinzufügen von<?phptatsächlich in den „HTML-Modus" zurückwechseln würde. - Der Code muss syntaktisch gültig und abgeschlossen sein. Ein fehlendes Semikolon oder eine nicht geschlossene geschweifte Klammer erzeugt einen Parse-Fehler. Seit PHP 7 wirft ein Parse-Fehler in
eval()eineParseError-Exception, die abgefangen werden kann — ältere Versionen gabenfalsezurück.
Rückgabewert
Wie eval() einen Wert zurückgibt, hängt davon ab, was der ausgewertete Code macht:
- Enthält der Code eine
return-Anweisung, gibteval()diesen Wert zurück. - Andernfalls gibt es
nullzurück.
<?php
$result = eval('return 2 + 3;');
echo $result; // 5Deshalb beendet ein return innerhalb von eval() den ausgewerteten string und nicht das gesamte Skript — die Kontrolle kehrt zur Zeile nach eval() zurück. Weitere Informationen zum Verhalten von return in regulären Funktionen finden Sie unter der return-Anweisung.
Einfaches Beispiel
Hier ist der einfachstmögliche Anwendungsfall — einen Code-string erstellen und ausführen:
Die Variable $code enthält gültigen PHP-Code, der Hello, world! ausgibt. eval() kompiliert und führt diesen string zur Laufzeit aus, sodass die Meldung angezeigt wird. Beachten Sie, dass kein <?php-Tag im string enthalten ist.
Fehler sicher abfangen
Da ungültiger Code eine ParseError-Exception auslöst, sollten Sie nicht vertrauenswürdigen oder generierten Code in einen try/catch-Block einschließen, damit ein fehlerhafter string nicht die gesamte Anfrage zum Absturz bringt:
<?php
try {
eval('echo "missing semicolon"'); // no terminating ;
} catch (ParseError $e) {
echo "Could not evaluate: " . $e->getMessage();
}Dadurch wird eine „Could not evaluate"-Meldung angezeigt anstatt eines schwerwiegenden Fehlers, sodass das Skript fortgesetzt werden kann.
Wann würde ich eval() verwenden?
Im modernen PHP so gut wie nie — und das ist die ehrliche Antwort. Legitime, eng begrenzte Anwendungsfälle umfassen:
- Template-/Ausdrucks-Engines, die eine benutzerdefinierte Mini-Sprache in PHP kompilieren (Twig und Blade tun konzeptionell Ähnliches, jedoch mit umfangreichem Sandboxing).
- Caching kompilierter Konfiguration als PHP, das später per
evalausgeführt wird — obwohl das Schreiben einer echten.php-Datei und die Verwendung vonincludeschneller und sicherer ist. - Schulungs- oder Debugging-Werkzeuge wie REPLs, bei denen der Eingabe vollständig vertraut werden kann.
Wenn der Wert, den Sie berechnen müssen, aus Daten besteht (Zahlen, JSON, eine Liste von Optionen), benötigen Sie eval() höchstwahrscheinlich nicht.
Sicherheitsrisiken
eval() führt alles aus, was ihm übergeben wird. Wenn ein Teil des strings durch Benutzereingaben beeinflusst werden kann, kann ein Angreifer beliebigen Code ausführen — Dateien lesen, Daten löschen oder den Server übernehmen. Dies ist eine klassische Remote Code Execution (RCE)-Schwachstelle.
<?php
// NEVER do this:
$expr = $_GET['expr']; // attacker-controlled
eval("\$answer = $expr;"); // attacker can inject any PHPEine Anfrage wie ?expr=1; system('rm -rf /') würde den eingeschleusten Befehl ausführen. Betrachten Sie jede eval()-Verwendung mit Benutzereingaben als garantierten Exploit.
Sicherere Alternativen
Bevor Sie eval() verwenden, prüfen Sie, ob eine der folgenden Alternativen Ihren Bedarf abdeckt:
| Ziel | Stattdessen verwenden |
|---|---|
| Strukturierte Daten parsen | json_decode() |
| Eine zur Laufzeit gewählte Funktion aufrufen | Callback / variable Funktionen |
| In einer Datei gespeicherten Code ausführen | include / require |
| Einen string einem Verhalten zuordnen | Ein match/switch oder ein array von Closures |
| Mathematische Ausdrücke auswerten | Eine dedizierte Ausdrucks-Parser-Bibliothek |
Fazit
eval() wertet einen string als PHP-Code zur Laufzeit aus und gibt das Ergebnis einer darin enthaltenen return-Anweisung zurück oder andernfalls null. Es ist ein mächtiges Werkzeug, aber auch eine der häufigsten Quellen von Sicherheitslücken — jede vom Benutzer kontrollierte Eingabe, die daran übergeben wird, ist ein Remote-Code-Execution-Fehler. Verwenden Sie es nur, wenn der Eingabe vollständig vertraut werden kann und kein eingebautes Konstrukt passt, schließen Sie es in einen try/catch-Block für ParseError ein, und bevorzugen Sie wann immer möglich die sichereren oben genannten Alternativen.