W3docs

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:

ParametroTipoDescrizione
$ftp_streamresourceLa connessione restituita da ftp_connect().
$commandstringIl 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 EXEC consente 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.

Attenzione

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 tramite SITE EXEC; è stata deprecata in PHP 5.3.0 e rimossa in PHP 7.0.0.
  • È stata rimossa perché SITE EXEC rappresenta 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 ssh2 o 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.

Esercitazione

Pratica
Qual è lo scopo del comando FTP exec in PHP?
Qual è lo scopo del comando FTP exec in PHP?
Was this page helpful?