Skip to Content
Course content

126: FTP Functions in PHP

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Most of the time, we handle files on the same server where our PHP code lives. But eventually, you'll run into a situation where you need to move data to a separate storage server or a legacy system that only speaks FTP. It's not as common as it used to be—thanks to S3 and cloud storage—but in corporate environments, FTP is still the "old reliable" that refuses to die.

To show you how this works, let's build a small utility that takes a local report file—something like a daily CSV export—and pushes it up to a remote backup server. I'm going to keep this simple, but I'll walk you through the logic I use when I'm scripting these things.

Establishing the Handshake

First, we need a connection. I usually store my credentials in a config file, but for this example, I'll just put them in variables. The core function here is ftp_connect(), followed by ftp_login(). One thing to remember: FTP is inherently insecure (it sends passwords in plain text), so if you're doing this in production, you'd really want to look at SFTP, but for the built-in PHP FTP functions, this is the flow.

$ftp_server = "ftp.example.com";
$ftp_user = "backup_user";
$ftp_pass = "secret_password";

// Establish the connection
$conn_id = ftp_connect($ftp_server) or die("Couldn't connect to $ftp_server");

// Log in
if (@ftp_login($conn_id, $ftp_user, $ftp_pass)) {
    echo "Connected successfully\n";
} else {
    echo "Login failed\n";
    die();
}

The "Hanging" Problem and Passive Mode

Here is where I almost tripped up when I first wrote this script. I tried to upload the file immediately after logging in, but the script just... sat there. It didn't time out; it just hung indefinitely. I realized I was behind a firewall that was blocking the server's attempt to open a data port back to my machine.

The fix is ftp_pasv(). By turning on passive mode, we tell the server that the client (our PHP script) will initiate the data connection. In 99% of modern environments, you want this set to true.

// I forgot this the first time! Always set passive mode for modern firewalls.
ftp_pasv($conn_id, true);

Shipping the Report File

Now that we have a stable connection, we use ftp_put(). This function needs the connection ID, the local path to the file, and the remote path where you want it to land. I like to use FTP_BINARY as the mode because it ensures the file isn't corrupted by the server trying to "helpfully" translate line endings between different operating systems.

$local_file = 'reports/daily_sales.csv';
$remote_file = 'backups/sales_' . date('Y-m-d') . '.csv';

if (ftp_put($conn_id, $remote_file, $local_file, FTP_BINARY)) {
    echo "Successfully uploaded $local_file to $remote_file\n";
} else {
    echo "There was a problem while uploading $local_file\n";
}

Cleaning Up the Connection

You wouldn't leave your front door wide open after you've finished moving furniture, and you shouldn't leave FTP connections hanging. It eats up server resources and can eventually hit a connection limit. A quick ftp_close() at the end is all you need.

// Close the connection
ftp_close($conn_id);
echo "Connection closed.";



📋 Practical Task

Build an FTP-based Log Archiver

Write a PHP script that performs the following specific task: Check if a local file named system_error.log exists. If it does, connect to a remote FTP server (you can use mock credentials), enable passive mode, and upload the log file to a directory called /archives/ on the server. The remote file must be renamed to include the current timestamp (e.g., system_error_20231027_1430.log) to prevent overwriting previous backups. Ensure you close the connection regardless of whether the upload succeeded or failed.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.