ftp_exec()
Warum PHP's ftp_exec() veraltet und entfernt wurde und wie man heute mit der ssh2-Erweiterung oder phpseclib sicher Remote-Befehle ausführt.
Die PHP-Funktion ftp_exec()
ftp_exec() war eine eingebaute PHP-Funktion, die einen entfernten FTP-Server aufforderte, einen Shell-Befehl in Ihrem Namen auszuführen. Sie wurde in PHP 5.3.0 als veraltet markiert und in PHP 7.0.0 entfernt, sodass sie in keiner modernen PHP-Version verfügbar ist. Diese Seite erklärt, was sie tat, warum sie verschwand und – was wichtiger ist – wie man heute sicher Remote-Befehle ausführt.
Wenn Sie nur Dateien über FTP verwalten müssen (hochladen, herunterladen, auflisten, umbenennen), benötigen Sie überhaupt keine Befehlsausführung. Lesen Sie die PHP-FTP-Übersicht und Funktionen wie ftp_connect() und ftp_raw().
Was ftp_exec() tat
Die Funktion nahm zwei Parameter entgegen und gab einen boolean-Wert zurück:
| Parameter | Typ | Beschreibung |
|---|---|---|
$ftp_stream | resource | Die von ftp_connect() zurückgegebene Verbindung. |
$command | string | Der auf dem FTP-Server auszuführende Befehl. |
Sie gab true zurück, wenn der Server den Befehl akzeptierte und ausführte, und false bei einem Fehler. Intern sendete sie den FTP-Befehl SITE EXEC, der nur funktioniert, wenn der Server diese Funktion explizit aktiviert hat.
Historische Syntax
bool ftp_exec(resource $ftp_stream, string $command)Die Signatur verwendete einen resource-Verbindungsbezeichner. Die objektorientierte Klasse FTP\Connection wurde in PHP 8.0 hinzugefügt – lange nachdem ftp_exec() bereits entfernt worden war –, sodass beide nie gleichzeitig existierten.
Warum sie entfernt wurde
Zwei Probleme machten ftp_exec() in der Praxis unbrauchbar:
- Sie war fast nie verfügbar.
SITE EXECerlaubt einem FTP-Client, beliebige Shell-Befehle auf dem Server auszuführen. Das ist ein klassisches Remote-Code-Execution-Risiko, weshalb gängige Server wie vsftpd und ProFTPD es standardmäßig deaktiviert ausliefern und die meisten Anbieter es nie aktiviert haben. - FTP selbst ist unsicher. Einfaches FTP überträgt Zugangsdaten und Daten im Klartext. Befehlsausführung auf einem unverschlüsselten Protokoll zu schichten, ist genau die falsche Richtung. (Wenn Sie FTP für Dateien verwenden müssen, bevorzugen Sie
ftp_ssl_connect()für FTPS.)
Da das Feature sowohl gefährlich als auch praktisch tot war, hat PHP es in 5.3.0 als veraltet markiert und es in 7.0.0 vollständig entfernt.
Der Aufruf von ftp_exec() in PHP 7.0 oder höher wirft einen Error: Call to undefined function ftp_exec(). Es gibt keinen direkten Ersatz innerhalb der FTP-Erweiterung — Remote-Befehlsausführung gehört zu SSH.
Sichere Remote-Befehlsausführung heute
Um einen Befehl auf einem entfernten Rechner von PHP aus auszuführen, verwenden Sie SSH, nicht FTP. Es gibt zwei Standardoptionen:
- Die
ssh2-Erweiterung – eine native PECL-Erweiterung, die libssh2 umschließt. - phpseclib – eine reine PHP-Bibliothek, die keine Erweiterung benötigt, was sie ideal für Shared Hosting macht.
Option 1: Die ssh2-Erweiterung
<?php
// 1. Open an SSH connection (default SSH port is 22)
$conn = ssh2_connect('example.com', 22);
if (!$conn) {
die("Could not connect to server.\n");
}
// 2. Authenticate
if (!ssh2_auth_password($conn, 'username', 'password')) {
die("SSH authentication failed.\n");
}
// 3. Run the command
$stream = ssh2_exec($conn, 'ls -al');
if ($stream === false) {
die("Failed to execute command.\n");
}
// 4. Read its output
stream_set_blocking($stream, true);
$output = stream_get_contents($stream);
echo $output;ssh2_connect() öffnet den verschlüsselten Kanal, ssh2_auth_password() meldet sich an und ssh2_exec() führt den Befehl aus und gibt einen Stream zurück. Den Stream mit stream_set_blocking() auf blockierend zu setzen, stellt sicher, dass Sie die vollständige Ausgabe lesen, bevor das Skript fortfährt – ein häufiger Fallstrick, der sonst zu leeren Ergebnissen führt.
Option 2: phpseclib (keine Erweiterung erforderlich)
<?php
require 'vendor/autoload.php';
use phpseclib3\Net\SSH2;
$ssh = new SSH2('example.com');
if (!$ssh->login('username', 'password')) {
exit('SSH login failed');
}
echo $ssh->exec('ls -al');Da phpseclib vollständig in PHP geschrieben ist, läuft es überall dort, wo PHP läuft – kein PECL-Build, keine serverseitige Erweiterung. Installieren Sie es mit composer require phpseclib/phpseclib.
Fehlerbehandlung
Überprüfen Sie stets den Rückgabewert, bevor Sie die Ausgabe lesen. Mit der ssh2-Erweiterung gibt ssh2_exec() bei einem Fehler false zurück:
<?php
$stream = ssh2_exec($conn, 'ls -al');
if ($stream === false) {
echo "Failed to execute the command.\n";
} else {
stream_set_blocking($stream, true);
echo stream_get_contents($stream);
}Für stärkere Sicherheitsgarantien bevorzugen Sie schlüsselbasierte Authentifizierung (ssh2_auth_pubkey_file()) gegenüber Passwörtern und interpolieren Sie niemals nicht vertrauenswürdige Eingaben direkt in einen Befehlsstring – verwenden Sie escapeshellarg() zur Absicherung der Argumente, um Command-Injection zu vermeiden.
Zusammenfassung
ftp_exec()führte einen Befehl auf einem FTP-Server überSITE EXECaus; es wurde in PHP 5.3.0 als veraltet markiert und in PHP 7.0.0 entfernt.- Es wurde entfernt, weil
SITE EXECein Remote-Code-Execution-Risiko darstellt, das die meisten Server deaktivieren, und weil FTP unverschlüsselt ist. - Für Remote-Befehle verwenden Sie heute SSH über die
ssh2-Erweiterung oder phpseclib – niemals FTP. - Für reine Dateiübertragungen ist die FTP-Erweiterung noch in Ordnung; beginnen Sie mit
ftp_connect(),ftp_login()und der PHP-FTP-Übersicht.