W3docs

ftp_exec()

Learn why PHP's ftp_exec() was deprecated and removed, and how to run remote commands securely today with the ssh2 extension or phpseclib.

The PHP ftp_exec() Function

ftp_exec() was a built-in PHP function that asked a remote FTP server to run a shell command on your behalf. It was deprecated in PHP 5.3.0 and removed in PHP 7.0.0, so it is unavailable in any modern PHP version. This page explains what it did, why it disappeared, and — more usefully — how to run remote commands safely today.

If you only need to manage files over FTP (upload, download, list, rename), you do not need command execution at all. See the PHP FTP overview and functions like ftp_connect() and ftp_raw().

What ftp_exec() Did

The function took two parameters and returned a boolean:

ParameterTypeDescription
$ftp_streamresourceThe connection returned by ftp_connect().
$commandstringThe command to run on the FTP server.

It returned true if the server accepted and ran the command, and false on failure. Under the hood it sent the FTP SITE EXEC command, which only works if the server explicitly enables that feature.

Historical Syntax

bool ftp_exec(resource $ftp_stream, string $command)

The signature used a resource connection identifier. The object-oriented FTP\Connection class was added in PHP 8.0 — long after ftp_exec() had already been removed — so the two never coexisted.

Why It Was Removed

Two problems made ftp_exec() unusable in practice:

  • It was almost never available. SITE EXEC lets an FTP client run arbitrary shell commands on the server. That is a textbook remote-code-execution risk, so mainstream servers such as vsftpd and ProFTPD ship with it disabled, and most hosts never turned it on.
  • FTP itself is insecure. Plain FTP sends credentials and data in clear text. Layering command execution on top of an unencrypted protocol is exactly the wrong direction. (If you must use FTP for files, prefer ftp_ssl_connect() for FTPS.)

Because the feature was both dangerous and effectively dead, PHP deprecated it in 5.3.0 and dropped it entirely in 7.0.0.

Warning

Calling ftp_exec() in PHP 7.0 or later throws an Error: Call to undefined function ftp_exec(). There is no drop-in replacement inside the FTP extension — remote command execution belongs to SSH.

Secure Remote Command Execution Today

To run a command on a remote machine from PHP, use SSH, not FTP. Two standard options exist:

  • The ssh2 extension — a native PECL extension wrapping libssh2.
  • phpseclib — a pure-PHP library that needs no extension, which makes it ideal on shared hosting.

Option 1: The ssh2 Extension

<?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() opens the encrypted channel, ssh2_auth_password() logs in, and ssh2_exec() runs the command and returns a stream. Setting the stream to blocking with stream_set_blocking() guarantees you read the full output before the script continues — a common gotcha that otherwise yields empty results.

Option 2: phpseclib (No Extension Required)

<?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');

Because phpseclib is written entirely in PHP, it runs anywhere PHP does — no PECL build, no server-level extension. Install it with composer require phpseclib/phpseclib.

Handling Errors

Always check the return value before reading output. With the ssh2 extension, ssh2_exec() returns false on failure:

<?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);
}

For stronger guarantees, prefer key-based authentication (ssh2_auth_pubkey_file()) over passwords, and never interpolate untrusted input directly into a command string — escape arguments with escapeshellarg() to avoid command injection.

Key Takeaways

  • ftp_exec() ran a command on an FTP server via SITE EXEC; it was deprecated in PHP 5.3.0 and removed in PHP 7.0.0.
  • It was removed because SITE EXEC is a remote-code-execution risk that most servers disable, and FTP is unencrypted.
  • For remote commands today, use SSH through the ssh2 extension or phpseclib — never FTP.
  • For plain file transfers, the FTP extension is still fine; start with ftp_connect(), ftp_login(), and the PHP FTP overview.

Practice

Practice
What is the purpose of the FTP exec command in PHP?
What is the purpose of the FTP exec command in PHP?
Was this page helpful?