ftp_exec()
Aprende por qué ftp_exec() fue eliminado en PHP y cómo ejecutar comandos remotos de forma segura con la extensión ssh2 o phpseclib.
La función ftp_exec() de PHP
ftp_exec() era una función integrada de PHP que pedía a un servidor FTP remoto ejecutar un comando de shell en tu nombre. Fue declarada obsoleta en PHP 5.3.0 y eliminada en PHP 7.0.0, por lo que no está disponible en ninguna versión moderna de PHP. Esta página explica qué hacía, por qué desapareció y, lo más útil, cómo ejecutar comandos remotos de forma segura hoy en día.
Si solo necesitas gestionar archivos a través de FTP (subir, descargar, listar, renombrar), no necesitas ejecución de comandos en absoluto. Consulta la descripción general de PHP FTP y funciones como ftp_connect() y ftp_raw().
Qué hacía ftp_exec()
La función recibía dos parámetros y devolvía un boolean:
| Parámetro | Tipo | Descripción |
|---|---|---|
$ftp_stream | resource | La conexión devuelta por ftp_connect(). |
$command | string | El comando que se ejecuta en el servidor FTP. |
Devolvía true si el servidor aceptaba y ejecutaba el comando, y false en caso de error. Internamente enviaba el comando FTP SITE EXEC, que solo funciona si el servidor habilita explícitamente esa característica.
Sintaxis histórica
bool ftp_exec(resource $ftp_stream, string $command)La firma usaba un identificador de conexión de tipo resource. La clase orientada a objetos FTP\Connection se añadió en PHP 8.0, mucho después de que ftp_exec() ya hubiera sido eliminada, por lo que las dos nunca coexistieron.
Por qué fue eliminada
Dos problemas hicieron que ftp_exec() fuera inutilizable en la práctica:
- Casi nunca estaba disponible.
SITE EXECpermite que un cliente FTP ejecute comandos de shell arbitrarios en el servidor. Eso es un riesgo textbook de ejecución remota de código, por lo que servidores populares como vsftpd y ProFTPD la tienen deshabilitada de serie, y la mayoría de los proveedores nunca la activaron. - FTP en sí mismo es inseguro. El FTP plano envía las credenciales y los datos en texto claro. Añadir ejecución de comandos sobre un protocolo sin cifrar es exactamente la dirección equivocada. (Si debes usar FTP para archivos, prefiere
ftp_ssl_connect()para FTPS.)
Como la funcionalidad era tanto peligrosa como efectivamente inutilizable, PHP la declaró obsoleta en 5.3.0 y la eliminó por completo en 7.0.0.
Llamar a ftp_exec() en PHP 7.0 o posterior lanza un Error: Call to undefined function ftp_exec(). No existe un reemplazo directo dentro de la extensión FTP — la ejecución de comandos remotos pertenece a SSH.
Ejecución segura de comandos remotos hoy en día
Para ejecutar un comando en una máquina remota desde PHP, usa SSH, no FTP. Existen dos opciones estándar:
- La extensión
ssh2— una extensión nativa de PECL que envuelve libssh2. - phpseclib — una biblioteca en PHP puro que no necesita ninguna extensión, lo que la hace ideal en hosting compartido.
Opción 1: La extensión 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() abre el canal cifrado, ssh2_auth_password() inicia sesión y ssh2_exec() ejecuta el comando y devuelve un stream. Configurar el stream como bloqueante con stream_set_blocking() garantiza que leas la salida completa antes de que continúe el script — un error habitual que de otro modo produce resultados vacíos.
Opción 2: phpseclib (sin extensión necesaria)
<?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');Dado que phpseclib está escrito completamente en PHP, funciona en cualquier lugar donde PHP esté disponible: sin compilación de PECL, sin extensión a nivel de servidor. Instálalo con composer require phpseclib/phpseclib.
Manejo de errores
Comprueba siempre el valor de retorno antes de leer la salida. Con la extensión ssh2, ssh2_exec() devuelve false en caso de error:
<?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);
}Para mayor seguridad, prefiere la autenticación basada en clave (ssh2_auth_pubkey_file()) en lugar de contraseñas, y nunca interpolates entrada no confiable directamente en una cadena de comandos — escapa los argumentos con escapeshellarg() para evitar inyección de comandos.
Conclusiones clave
ftp_exec()ejecutaba un comando en un servidor FTP a través deSITE EXEC; fue declarada obsoleta en PHP 5.3.0 y eliminada en PHP 7.0.0.- Fue eliminada porque
SITE EXECes un riesgo de ejecución remota de código que la mayoría de los servidores deshabilitan, y FTP no está cifrado. - Para comandos remotos hoy en día, usa SSH a través de la extensión
ssh2o phpseclib — nunca FTP. - Para transferencias de archivos simples, la extensión FTP sigue siendo válida; comienza con
ftp_connect(),ftp_login()y la descripción general de PHP FTP.