Start · Sprachen · PHP · Referenz · pcntl_exec

pcntl_exec

Funktion

Ersetzt den aktuellen PHP-Prozess durch ein externes Programm (<code>execve(2)</code>-Syscall) — der Prozess kehrt nicht zurück, wenn der Aufruf erfolgreich war.

seit PHP 4.2.0 Kategorie: misc

Signatur

pcntl_exec(string $path, array $args = [], array $env_vars = []): bool

Beschreibung

pcntl_exec() führt das unter $path angegebene Programm im aktuellen Prozessraum aus, indem es den POSIX-Syscall execve(2) aufruft. Das bedeutet: Sobald der Aufruf erfolgreich ist, wird der PHP-Prozess vollständig durch das neue Programm ersetzt. PHP-Code nach dem Aufruf wird nie mehr ausgeführt.

Die Funktion ist eng verwandt mit dem klassischen Unix-Pattern fork-exec: Man erzeugt mit pcntl_fork() einen Kind-Prozess und ruft in diesem pcntl_exec() auf, um ein externes Binary zu starten, während der Eltern-Prozess weiterläuft. Dieses Muster wird etwa zum Starten von Sub-Prozessen, Daemon-Prozessen oder zur Prozesskettensteuerung eingesetzt.

Optionale Argumente werden als numerisches Array $args übergeben und entsprechen argv[1], argv[2], … des Zielprogramms. Über $env_vars lassen sich Umgebungsvariablen als assoziatives Array ('VARIABLE' => 'Wert') definieren; wird das Array weggelassen, erbt der neue Prozess die aktuelle Umgebung.

Die Funktion steht nur auf POSIX-kompatiblen Systemen (Linux, macOS, BSD) zur Verfügung und erfordert die Kompilierung von PHP mit --enable-pcntl. Sie ist nicht für den Einsatz in Web-SAPIs (Apache, FPM) geeignet, sondern ausschließlich für CLI-Skripte.

Parameter

Name Typ Default Beschreibung
$path Pflicht string Absoluter Dateipfad zum auszuführenden Binary oder Skript (z. B. /usr/bin/python3). Der Pfad muss ausführbar sein.
$args array [] Numerisches Array der Kommandozeilen-Argumente, die dem Programm als argv[1], argv[2], … übergeben werden. argv[0] (Programmname) wird automatisch auf $path gesetzt.
$env_vars array [] Assoziatives Array der Umgebungsvariablen in der Form ['NAME' => 'Wert']. Wird ein leeres Array übergeben, erhält der neue Prozess eine leere Umgebung. Wird der Parameter ganz weggelassen, wird die aktuelle Umgebung vererbt.

Rückgabewert

Typ
bool
Beschreibung
Gibt false zurück, wenn das Programm nicht gestartet werden konnte (z. B. Datei nicht gefunden, keine Ausführrechte). Bei Erfolg kehrt die Funktion nicht zurück, da der Prozess ersetzt wurde.

Beispiele

Aktuellen Prozess durch ls ersetzen

<?php
// Einfachstes Beispiel: PHP-Prozess wird durch /bin/ls ersetzt.
// Alles danach wird NICHT ausgeführt.
$result = pcntl_exec('/bin/ls', ['-la', '/tmp']);

// Hierher kommt man nur, wenn exec fehlgeschlagen ist:
if ($result === false) {
    echo 'Fehler: ' . posix_strerror(posix_get_last_error()) . PHP_EOL;
}
Ausgabe von ls -la /tmp (direkt im Terminal)

fork-exec-Pattern: Kind-Prozess startet externes Programm

<?php
// Typisches Unix-Pattern: fork, dann exec im Kind-Prozess.
$pid = pcntl_fork();

if ($pid === -1) {
    exit('fork() fehlgeschlagen');
}

if ($pid === 0) {
    // Kind-Prozess: ersetzt sich selbst durch curl
    pcntl_exec('/usr/bin/curl', [
        '--silent',
        '--output', '/tmp/result.html',
        'https://example.com'
    ]);
    // Nur erreichbar bei Fehler:
    exit(1);
}

// Eltern-Prozess wartet auf den Kind-Prozess
pcntl_waitpid($pid, $status);

if (pcntl_wifexited($status)) {
    $code = pcntl_wexitstatus($status);
    echo "curl beendet mit Exit-Code: {$code}" . PHP_EOL;
}
curl beendet mit Exit-Code: 0

Umgebungsvariablen explizit setzen

<?php
// Programm mit einer definierten, minimalen Umgebung starten.
pcntl_exec(
    '/usr/bin/env',
    [],
    [
        'PATH'   => '/usr/local/bin:/usr/bin:/bin',
        'HOME'   => '/tmp',
        'LANG'   => 'de_DE.UTF-8',
    ]
);
// Ausgabe (falls exec erfolgreich): die drei Umgebungsvariablen
HOME=/tmp LANG=de_DE.UTF-8 PATH=/usr/local/bin:/usr/bin:/bin

// Wichtig · Fallstricke

Sicherheit: Nutzer-Eingaben dürfen niemals ungefiltert als $path oder in $args übergeben werden. Auch wenn pcntl_exec() keine Shell verwendet (im Gegensatz zu shell_exec()), sind Path-Traversal-Angriffe (../../bin/sh) möglich. Pfade immer validieren und auf eine Allowlist beschränken.

Kein Rücksprung bei Erfolg: Das Programm ersetzt den Prozess vollständig. register_shutdown_function()-Callbacks, Destruktoren und finally-Blöcke werden nicht ausgeführt. Ressourcen (Datenbankverbindungen, Dateisperren) sollten vor dem Aufruf explizit freigegeben werden.

Nur CLI: Die PCNTL-Extension ist explizit für CLI-Skripte konzipiert. Der Einsatz unter Web-SAPIs (Apache mod_php, FPM) kann zu schwer vorhersehbarem Verhalten führen und sollte vermieden werden.

argv[0]: Das neue Programm sieht als argv[0] den Wert von $path. Es gibt keine Möglichkeit, argv[0] separat zu überschreiben.