ftp_exec()
Scopri perché ftp_exec() è stata deprecata e rimossa da PHP e come eseguire comandi remoti in modo sicuro con l'estensione ssh2 o phpseclib.
La funzione PHP ftp_exec()
ftp_exec() era una funzione PHP integrata che chiedeva a un server FTP remoto di eseguire un comando di shell per conto dell'utente. È stata deprecata in PHP 5.3.0 e rimossa in PHP 7.0.0, quindi non è disponibile in nessuna versione moderna di PHP. Questa pagina spiega cosa faceva, perché è scomparsa e — cosa più utile — come eseguire comandi remoti in modo sicuro oggi.
Se devi solo gestire file tramite FTP (caricamento, download, elenco, rinomina), non hai bisogno dell'esecuzione di comandi. Consulta la panoramica PHP FTP e funzioni come ftp_connect() e ftp_raw().
Cosa faceva ftp_exec()
La funzione accettava due parametri e restituiva un boolean:
| Parametro | Tipo | Descrizione |
|---|---|---|
$ftp_stream | resource | La connessione restituita da ftp_connect(). |
$command | string | Il comando da eseguire sul server FTP. |
Restituiva true se il server accettava ed eseguiva il comando, e false in caso di errore. Internamente inviava il comando FTP SITE EXEC, che funziona solo se il server abilita esplicitamente tale funzionalità.
Sintassi storica
bool ftp_exec(resource $ftp_stream, string $command)La firma utilizzava un identificatore di connessione resource. La classe orientata agli oggetti FTP\Connection è stata aggiunta in PHP 8.0 — molto tempo dopo che ftp_exec() era già stata rimossa — quindi le due non hanno mai coesistito.
Perché è stata rimossa
Due problemi rendevano ftp_exec() inutilizzabile in pratica:
- Era quasi mai disponibile.
SITE EXECconsente a un client FTP di eseguire comandi di shell arbitrari sul server. Questo rappresenta un classico rischio di esecuzione di codice remoto, quindi i server principali come vsftpd e ProFTPD vengono distribuiti con questa funzione disabilitata, e la maggior parte degli host non l'ha mai attivata. - FTP stesso è insicuro. Il protocollo FTP semplice trasmette credenziali e dati in chiaro. Aggiungere l'esecuzione di comandi sopra un protocollo non crittografato è esattamente la direzione sbagliata. (Se devi usare FTP per i file, preferisci
ftp_ssl_connect()per FTPS.)
Poiché la funzionalità era sia pericolosa che praticamente inutilizzata, PHP l'ha deprecata nella versione 5.3.0 e rimossa completamente nella 7.0.0.
Chiamare ftp_exec() in PHP 7.0 o versioni successive genera un Error: Call to undefined function ftp_exec(). Non esiste un sostituto diretto all'interno dell'estensione FTP — l'esecuzione di comandi remoti appartiene a SSH.
Esecuzione sicura di comandi remoti oggi
Per eseguire un comando su una macchina remota da PHP, usa SSH, non FTP. Esistono due opzioni standard:
- L'estensione
ssh2— un'estensione PECL nativa che racchiude libssh2. - phpseclib — una libreria PHP pura che non richiede alcuna estensione, il che la rende ideale su hosting condivisi.
Opzione 1: l'estensione ssh2
<?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() apre il canale crittografato, ssh2_auth_password() esegue il login e ssh2_exec() esegue il comando e restituisce uno stream. Impostare lo stream in modalità bloccante con stream_set_blocking() garantisce di leggere l'output completo prima che lo script continui — un errore comune che altrimenti produce risultati vuoti.
Opzione 2: phpseclib (nessuna estensione richiesta)
<?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');Poiché phpseclib è scritto interamente in PHP, funziona ovunque funzioni PHP — nessuna build PECL, nessuna estensione a livello di server. Installalo con composer require phpseclib/phpseclib.
Gestione degli errori
Verifica sempre il valore restituito prima di leggere l'output. Con l'estensione ssh2, ssh2_exec() restituisce false in caso di errore:
<?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);
}Per maggiori garanzie, preferisci l'autenticazione basata su chiave (ssh2_auth_pubkey_file()) rispetto alle password, e non interpolare mai input non attendibile direttamente in una stringa di comando — usa escapeshellarg() per effettuare l'escape degli argomenti ed evitare l'iniezione di comandi.
Punti chiave
ftp_exec()eseguiva un comando su un server FTP tramiteSITE EXEC; è stata deprecata in PHP 5.3.0 e rimossa in PHP 7.0.0.- È stata rimossa perché
SITE EXECrappresenta un rischio di esecuzione di codice remoto che la maggior parte dei server disabilita, e FTP non è crittografato. - Per i comandi remoti oggi, usa SSH tramite l'estensione
ssh2o phpseclib — mai FTP. - Per i semplici trasferimenti di file, l'estensione FTP va ancora bene; inizia con
ftp_connect(),ftp_login()e la panoramica PHP FTP.