# PHP auf der Kommandozeile (CLI)

> PHP CLI erklärt: Unterschiede zur Web-Version, wichtige Optionen wie -l, -m und --ini, Cronjobs, eingebauter Webserver und warum php -v oft täuscht.

Quelle: https://phpsos.de/php/php-cli/  
Stand: 25.10.2026  
Anbieter: PHP SOS, PHP-Notfallhilfe und Server-Sicherheit. Soforthilfe per WhatsApp: https://wa.me/491736494914?text=Hallo%20PHP%20SOS%2C%20wir%20brauchen%20Hilfe%20mit%20unserem%20PHP-Server.%20Firma%3A%20%E2%80%A6%20Website%3A%20%E2%80%A6

**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
<?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:

1. **`php -v`** zeigt die Versionsnummer der CLI.
2. **`php --ini`** zeigt, welche Konfigurationsdateien geladen werden.
3. **`php -m`** listet die einkompilierten und geladenen Module.
4. **`php -i`** ruft `phpinfo()` auf und gibt das Ergebnis als Text aus.
5. **`php -l datei.php`** prüft nur die Syntax (Lint). Seit PHP 8.3 auch für mehrere Dateien auf einmal.
6. **`php -r 'code'`** führt Code direkt aus, ohne `<?php`.
7. **`php -d name=wert`** setzt eine INI-Einstellung für diesen Aufruf.
8. **`php -n`** ignoriert die php.ini vollständig.
9. **`php --ri name`** zeigt die Konfiguration einer Erweiterung.

```bash
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 -v` zeigt 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](https://phpsos.de/php2shell/php-version-pruefen/) und im Beitrag [Warum php -v dieselbe Nummer zeigt](https://phpsos.de/blog/php-v-zeigt-alte-nummer/).
- **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](https://phpsos.de/blog/cronjobs-als-hintertuer/).
- **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](https://phpsos.de/leistungen/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.

## Quellen

- [PHP-Handbuch: PHP auf der Kommandozeile](https://www.php.net/manual/en/features.commandline.php)
- [PHP-Handbuch: Unterschiede der CLI-SAPI](https://www.php.net/manual/en/features.commandline.differences.php)
- [PHP-Handbuch: CLI-Optionen](https://www.php.net/manual/en/features.commandline.options.php)
- [PHP-Handbuch: Eingebauter Webserver](https://www.php.net/manual/en/features.commandline.webserver.php)
