W3docs

PHP FTP

FTP (File Transfer Protocol) is a standard network protocol used to transfer files from one host to another over a TCP-based network. PHP provides a built-in

Introduction

FTP (File Transfer Protocol) is a standard network protocol for transferring files between a client and a server over a TCP connection. PHP ships with a built-in FTP extension (ext-ftp) that lets your scripts log in to a remote server and move files programmatically — useful for deploying assets, syncing backups, or pulling data feeds from a partner's server.

This chapter covers the full workflow: connecting, logging in, switching to passive mode, uploading and downloading, listing and managing remote files, and finally closing the connection cleanly. It also explains the security caveats you must know before using plain FTP in production.

Security note first. Plain FTP sends your username, password, and file contents unencrypted. For anything sensitive, use ftp_ssl_connect() (FTP over TLS) or prefer SFTP (SSH File Transfer Protocol), which the FTP extension does not speak — use the PHP SSH2 extension or a library such as phpseclib for SFTP.

The typical FTP workflow

Every FTP script follows the same shape, regardless of which operation you perform:

  1. Connect to the server — ftp_connect() (or ftp_ssl_connect() for FTPS).
  2. Authenticateftp_login().
  3. Configure — usually ftp_pasv($conn, true) to enable passive mode.
  4. Transfer / manage files — ftp_put(), ftp_get(), ftp_nlist(), etc.
  5. Closeftp_close().

Connecting to an FTP Server

Establish a connection with ftp_connect(). It takes the hostname (and optional port and timeout) and returns an FTP\Connection object on success (a resource before PHP 8.1), or false on failure.

<?php

$conn = ftp_connect("ftp.example.com", 21, 10); // host, port, timeout (seconds)
if ($conn === false) {
    die("Could not connect to FTP server");
}
echo "Connected.";

Note that connecting does not log you in — at this point you have an anonymous, unauthenticated channel. You still have to call ftp_login() before the server will let you do anything useful.

Using FTPS (FTP over TLS)

To encrypt the control and data channels, swap ftp_connect() for ftp_ssl_connect(). The rest of the API is identical:

<?php

$conn = ftp_ssl_connect("ftp.example.com");
if ($conn === false) {
    die("Could not open a secure FTP connection");
}

Logging In and Passive Mode

After connecting, authenticate with ftp_login(). For public servers that allow anonymous access, use the username anonymous with an email-like password.

<?php

$conn = ftp_connect("ftp.example.com");

if (!ftp_login($conn, "username", "password")) {
    ftp_close($conn);
    die("Login failed");
}

// Most networks behind a firewall/NAT require passive mode.
ftp_pasv($conn, true);

echo "Logged in.";

Why passive mode matters. In active mode the server opens a data connection back to your client, which firewalls and NAT routers almost always block. In passive mode the client opens the data connection to the server instead, so it works behind firewalls. As a rule of thumb, call ftp_pasv($conn, true) right after logging in. It must be set after ftp_login(), not before.

Uploading Files

Use ftp_put() to send a local file to the server. Its signature is ftp_put($conn, $remote_file, $local_file, $mode), where $mode is FTP_BINARY or FTP_ASCII.

<?php

$conn = ftp_connect("ftp.example.com");
ftp_login($conn, "username", "password");
ftp_pasv($conn, true);

if (ftp_put($conn, "/public_html/report.pdf", "report.pdf", FTP_BINARY)) {
    echo "Upload successful";
} else {
    echo "Upload failed";
}

ftp_close($conn);

FTP_BINARY vs FTP_ASCII. Use FTP_BINARY for everything that is not plain text — images, PDFs, archives, executables — because ASCII mode rewrites line endings and will corrupt binary data. Use FTP_ASCII only when you specifically want line endings translated between platforms for text files. When in doubt, choose FTP_BINARY; it is the safe default.

For large files you can upload non-blocking with ftp_nb_put(), which lets your script do other work between chunks.

Downloading Files

ftp_get() retrieves a remote file to the local filesystem. The argument order is ftp_get($conn, $local_file, $remote_file, $mode) — note that the local destination comes first, the opposite of ftp_put(). Mixing these up is the single most common FTP bug.

<?php

$conn = ftp_connect("ftp.example.com");
ftp_login($conn, "username", "password");
ftp_pasv($conn, true);

// local_file first, then remote_file
if (ftp_get($conn, "backup.zip", "/backups/backup.zip", FTP_BINARY)) {
    echo "Download successful";
} else {
    echo "Download failed";
}

ftp_close($conn);

Listing and Managing Remote Files

The FTP extension does much more than transfer files. Common management functions include:

FunctionPurpose
ftp_nlist($conn, $dir)Array of file names in a directory
ftp_rawlist($conn, $dir)Detailed ls -l-style listing
ftp_size($conn, $file)File size in bytes (-1 on error)
ftp_mkdir($conn, $dir)Create a directory
ftp_rmdir($conn, $dir)Remove an (empty) directory
ftp_delete($conn, $file)Delete a file
ftp_rename($conn, $from, $to)Rename / move a file
ftp_chdir($conn, $dir)Change the working directory
ftp_pwd($conn)Current working directory
ftp_chmod($conn, 0644, $file)Change file permissions
<?php

$conn = ftp_connect("ftp.example.com");
ftp_login($conn, "username", "password");
ftp_pasv($conn, true);

$files = ftp_nlist($conn, "/public_html");
foreach ($files as $file) {
    echo $file, " — ", ftp_size($conn, $file), " bytes\n";
}

ftp_close($conn);

Closing the Connection

Always release the connection with ftp_close() when you are done. Wrapping the workflow in try/finally guarantees the socket is closed even if an error is thrown midway:

<?php

$conn = ftp_connect("ftp.example.com");
if (!$conn || !ftp_login($conn, "username", "password")) {
    die("Connection or login failed");
}

try {
    ftp_pasv($conn, true);
    ftp_put($conn, "/public_html/index.html", "index.html", FTP_BINARY);
} finally {
    ftp_close($conn);
}

Best Practices and Gotchas

  • Prefer FTPS or SFTP. Never send credentials over plain FTP across the public internet.
  • Always enable passive mode (ftp_pasv) unless you have a specific reason not to.
  • Pick the right transfer modeFTP_BINARY for binary data, FTP_ASCII only for text where line-ending translation is wanted.
  • Watch the argument orderftp_put is (remote, local), ftp_get is (local, remote).
  • Always close the connection with ftp_close().
  • Check every return value. FTP functions return false on failure rather than throwing, so silent failures are easy to miss.
  • ext-ftp must be enabled. Confirm with extension_loaded('ftp'); if it returns false, enable the extension in your php.ini.

Practice

Practice
What are the functions of FTP in PHP?
What are the functions of FTP in PHP?
Was this page helpful?