ftp_get()
The ftp_get() function is a PHP built-in function that retrieves a file from the FTP server and saves it to a local file. The function takes three parameters:
What is ftp_get()?
ftp_get() is a PHP built-in function that downloads a file from an FTP server and writes it to a local file on your machine. It is the read counterpart of ftp_put(), which uploads. Use it whenever you need to pull a file (a backup, a log, a report) from a remote server over FTP.
This page covers what ftp_get() does, its parameters and return value, a complete working flow (connect → log in → download → close), how to handle failures, and the common gotchas that trip people up (transfer mode, passive mode, and resuming partial downloads).
Parameters
ftp_get() takes five parameters — three required and two optional:
| Parameter | Required | Description |
|---|---|---|
ftp_stream | Yes | The connection identifier returned by ftp_connect() (or ftp_ssl_connect()). |
local_file | Yes | The local path the downloaded data is written to. An existing file is overwritten. |
remote_file | Yes | The path of the file to fetch from the server. |
mode | No | Transfer mode: FTP_BINARY (default) or FTP_ASCII. |
resumepos | No | Byte offset at which to start the transfer. Defaults to 0 (start of file). |
Return value
The function returns a boolean: true on success, false on failure. Always check it — a failed download does not throw an exception by default.
FTP_BINARY vs FTP_ASCII
FTP_BINARY transfers the file byte-for-byte and is correct for almost everything: images, PDFs, archives, executables, and even most text files. FTP_ASCII performs automatic line-ending conversion between the server and client conventions, so use it only for plain-text files where you actually want that conversion. Using FTP_ASCII on a binary file will corrupt it, so when in doubt, choose FTP_BINARY.
Syntax of ftp_get()
bool ftp_get ( resource $ftp_stream , string $local_file , string $remote_file [, int $mode = FTP_BINARY [, int $resumepos = 0 ]] )Note: In PHP 8.1+, the resource type for FTP connections was replaced by an Ftp\Connection object, and the mode parameter became optional (defaulting to FTP_BINARY). The legacy resource signature above is kept for backward compatibility — your code does not need to change.
Usage of ftp_get()
To use ftp_get(), you first establish a connection with ftp_connect() and authenticate with ftp_login(). Here is the full flow:
Downloading a file with ftp_get()
<?php
// 1. Set up an FTP connection
$conn = ftp_connect('ftp.example.com');
if (!$conn) {
die("Could not connect to FTP server.\n");
}
// 2. Log in with your FTP credentials
if (!ftp_login($conn, 'username', 'password')) {
ftp_close($conn);
die("Login failed.\n");
}
// 3. Switch to passive mode (required behind most firewalls/NAT)
ftp_pasv($conn, true);
// 4. Download the remote file into a local path
if (ftp_get($conn, '/local/directory/local_file.txt', 'remote_file.txt', FTP_BINARY)) {
echo "File retrieved successfully.\n";
} else {
echo "Failed to retrieve the file.\n";
}
// 5. Close the FTP connection
ftp_close($conn);The steps are always the same: connect, log in, optionally enable passive mode, download, then close. Passive mode (ftp_pasv()) is enabled here because most clients sit behind a firewall or NAT and active-mode transfers would otherwise hang or fail. Note that you must call ftp_pasv() after logging in.
Error handling in ftp_get()
ftp_get() returns false on failure rather than throwing, so check the return value explicitly. Common causes are a missing remote file, insufficient permissions, or a local path that is not writable. PHP also emits a warning, which you can capture for logging:
Capturing the reason a download failed
<?php
// $conn is an open, logged-in FTP connection
$ok = @ftp_get($conn, '/local/directory/local_file.txt', 'remote_file.txt', FTP_BINARY);
if ($ok === false) {
$error = error_get_last();
echo "Failed to retrieve the file: " . ($error['message'] ?? 'unknown error') . "\n";
} else {
echo "File retrieved successfully.\n";
}The @ suppresses the raw PHP warning so you can format your own message, while error_get_last() still gives you the underlying detail for a log.
Resuming an interrupted download
The optional resumepos parameter lets you continue a download that was cut off, instead of starting over. Pass the current size of the partially downloaded local file as the byte offset:
Resuming with resumepos
<?php
// $conn is an open, logged-in FTP connection
$local = '/local/directory/big_archive.zip';
// Continue from however many bytes we already have locally
$offset = file_exists($local) ? filesize($local) : 0;
if (ftp_get($conn, $local, 'big_archive.zip', FTP_BINARY, $offset)) {
echo "Download complete.\n";
} else {
echo "Resume failed.\n";
}Resuming only works reliably with FTP_BINARY and on servers that support the REST command. For large transfers you can also look at the non-blocking variant ftp_nb_get(), which downloads in the background so your script can do other work.
Related functions
ftp_put()— upload a local file to the server (the inverse offtp_get()).ftp_fget()— download into an already-open file handle instead of a path.ftp_size()— get the size of a remote file before downloading.ftp_connect()andftp_login()— open and authenticate the connection.ftp_close()— close the connection when you are done.
Summary
ftp_get() downloads a remote file over FTP and saves it locally, returning true on success and false on failure. Connect and log in first, prefer FTP_BINARY unless you specifically need ASCII line-ending conversion, enable passive mode when you are behind a firewall, and always check the return value so failures do not pass silently.