Kurz gesagt: Die PHP CLI (Command Line Interface) ist die Variante von PHP für die Kommandozeile. Sie führt Skripte ohne Webserver aus, etwa für Cronjobs, Composer oder Wartungsaufgaben. Sie hat eigene Standardwerte, oft eine eigene php.ini und manchmal sogar eine andere Version als die Website. Deshalb ist php -v kein verlässlicher Nachweis dafür, dass die Website nach PHP2Shell gepatcht ist.
Was ist die PHP CLI?
Das PHP-Handbuch nennt zwei Haupteinsatzgebiete von PHP: Skripte für Websites und Skripte auf der Kommandozeile. Für Letzteres gibt es eine eigene SAPI mit dem Namen cli. Sie braucht weder Webserver noch Browser, nur den PHP-Interpreter. Laut Handbuch eignet sie sich besonders für Aufgaben, die regelmäßig per Cron unter Linux oder über die Aufgabenplanung unter Windows laufen.
Typische Beispiele im Unternehmensalltag: nächtliche Importe im Shop, Newsletter-Versand, Bereinigung von Caches, Updates über Composer oder die Kommandozeilenwerkzeuge von CMS wie WP-CLI oder der Symfony-Konsole. Unter Windows heißt die Datei php.exe, die CGI-Variante php-cgi.exe.
Anders als PHP-FPM ist die CLI kein Dienst. Jeder Aufruf startet einen neuen Prozess, liest laut Handbuch die Konfiguration neu ein und endet, wenn das Skript fertig ist. Ein Neustart nach einem Update ist deshalb nicht nötig. Ausnahmen sind lang laufende Prozesse, die per CLI gestartet werden, etwa Warteschlangen-Worker von Frameworks oder Daemons unter systemd oder Supervisor. Sie laufen tagelang mit dem einmal geladenen Interpreter und müssen nach einem PHP-Update genauso neu gestartet werden wie Web-Worker.
Für Geschäftsführung und Projektleitung heißt das: Auch Hintergrundaufgaben gehören ins Inventar und in jeden Update-Plan.
Wie unterscheidet sich die CLI von der Web-Version?
Die CLI überschreibt laut Handbuch einige Einstellungen fest. Sie lassen sich nicht über die php.ini ändern, nur zur Laufzeit per ini_set():
| Direktive | Wert in der CLI | Begründung laut Handbuch |
|---|---|---|
html_errors |
aus | HTML-Tags stören im Terminal |
implicit_flush |
an | Ausgaben sollen sofort erscheinen |
max_execution_time |
0 (unbegrenzt) | Kommandozeilenskripte laufen oft lange |
register_argc_argv |
an | Skripte erhalten immer $argc und $argv |
output_buffering |
aus | fest verdrahtet, Pufferfunktionen bleiben nutzbar |
max_input_time |
aus | die CLI kennt kein GET, POST oder Uploads |
Ein weiterer Unterschied: Die CLI wechselt nicht in das Verzeichnis des Skripts. Wer php -f ordner/skript.php aus /tmp aufruft, arbeitet weiter in /tmp. Relative Pfade in Cronjobs sind deshalb eine häufige Fehlerquelle.
Ein kleines Skript, das nur auf der Kommandozeile laufen soll:
<?php
if (PHP_SAPI !== 'cli') {
http_response_code(403);
exit('Nur für die Kommandozeile.');
}
$tage = (int) ($argv[1] ?? 30);
$grenze = time() - $tage * 86400;
$alt = 0;
foreach (glob(__DIR__ . '/cache/*.tmp') ?: [] as $datei) {
if (filemtime($datei) < $grenze) { $alt++; }
}
fwrite(STDOUT, "Dateien älter als $tage Tage: $alt\n");
Die Prüfung auf PHP_SAPI verhindert, dass ein Wartungsskript über den Browser ausgelöst wird, falls es versehentlich im Webverzeichnis liegt. Das Handbuch rät ausdrücklich, die SAPI so zu prüfen statt sich auf das Vorhandensein von $argv zu verlassen.
Die wichtigsten Optionen der PHP CLI
Die folgenden Optionen stammen aus der Optionsübersicht des PHP-Handbuchs und sind für Admins besonders nützlich:
php -vzeigt die Versionsnummer der CLI.php --inizeigt, welche Konfigurationsdateien geladen werden.php -mlistet die einkompilierten und geladenen Module.php -iruftphpinfo()auf und gibt das Ergebnis als Text aus.php -l datei.phpprüft nur die Syntax (Lint). Seit PHP 8.3 auch für mehrere Dateien auf einmal.php -r 'code'führt Code direkt aus, ohne<?php.php -d name=wertsetzt eine INI-Einstellung für diesen Aufruf.php -nignoriert die php.ini vollständig.php --ri namezeigt die Konfiguration einer Erweiterung.
php --ini
php -m | grep -i -E "opcache|sodium|pdo"
php --ri session | grep upload_progress
php -l src/Controller.php src/Model.php
Der eingebaute Webserver: nur für die Entwicklung
Mit php -S localhost:8000 startet die CLI einen kleinen Webserver. Die Beispielausgabe im Handbuch nennt PHP 5.4.0 als Ausgangspunkt. Das Handbuch ist eindeutig: Der Server dient der Entwicklung, ist kein vollwertiger Webserver, soll nicht in öffentlichen Netzen und nicht in der Produktion laufen. Läuft er auf einem Server dauerhaft und von außen erreichbar, ist das ein Befund, den Sie abstellen sollten.
CLI, Cron und Sicherheit nach PHP2Shell
Die bekannten Meldungen zu PHP2Shell nennen PHP-FPM, mod_php, php-cgi, FrankenPHP und LiteSpeed als betroffene Betriebsarten. Die CLI verarbeitet keine Anfragen aus dem Netz. Für die Sicherheit ist sie trotzdem in dreifacher Hinsicht wichtig:
- Falscher Nachweis:
php -vzeigt die CLI-Version. Die Website kann eine andere Version nutzen, und Distributions-Backports ändern die angezeigte Nummer oft nicht. Wie Sie den Stand richtig belegen, steht unter PHP-Version und Patchstand prüfen und im Beitrag Warum php -v dieselbe Nummer zeigt. - Persistenz über Cron: Angreifer nutzen nach einem Einbruch gern Cronjobs, die ein PHP-Skript regelmäßig starten. Hinweise zur Suche gibt Versteckte Cronjobs als Hintertür erkennen.
- Gleiches Paket: Die CLI stammt meist aus derselben Paketquelle wie PHP-FPM und gehört ins Update.
Wie hilft PHP SOS konkret?
- Versionen abgleichen: Wir vergleichen CLI- und Web-Stand und belegen, welche Version Ihre Website wirklich ausliefert.
- Cronjobs prüfen: Wir listen alle geplanten PHP-Aufgaben aller Benutzer und ordnen sie ihren Anwendungen zu.
- Wartung absichern: Wir verschieben Wartungsskripte aus dem Webverzeichnis und setzen SAPI-Prüfungen.
- Dauerhaft betreuen: Im Security-Wartungsvertrag halten wir CLI, Web-SAPI und Cronjobs gemeinsam aktuell.
Häufige Fragen
Zeigt php -v die Version meiner Website?
Nicht unbedingt. php -v zeigt die Version der Kommandozeilen-Variante. Die Website kann über eine andere PHP-FPM-Version oder ein Apache-Modul laufen. Für die Website zählt der Stand der Web-SAPI, den Sie über den Dienst oder eine kurzzeitige Prüfdatei ermitteln.
Warum laufen CLI-Skripte unbegrenzt lange?
Laut PHP-Handbuch setzt die CLI max_execution_time fest auf 0, also unbegrenzt, weil Skripte auf der Kommandozeile oft lange Aufgaben erledigen. Begrenzen lässt sich die Laufzeit über das Skript selbst oder über Werkzeuge wie timeout.
Darf ich den eingebauten Webserver php -S produktiv nutzen?
Nein. Das Handbuch beschreibt ihn als Hilfe für die Entwicklung, nicht als vollwertigen Webserver, und rät von der Nutzung in öffentlichen Netzen und in der Produktion ab. Für Live-Systeme gehören Apache, Nginx oder LiteSpeed mit PHP-FPM davor.
Ist OPcache auf der Kommandozeile aktiv?
Standardmäßig nicht. opcache.enable_cli steht laut Handbuch auf 0. Für kurze Skripte bringt der Cache ohnehin wenig, weil jeder Aufruf ein neuer Prozess ist.