PHP
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Functions
-
Section 4: Object-Oriented PHP
-
Section 5: Working with Data
-
Section 6: Modern PHP (PHP 8)
-
Section 7: Working with Files and Networking
-
Section 8: Common PHP Frameworks Overview
-
Section 9: Tooling and Ecosystem
-
Section 10: Practical Projects
-
Section 11: Interview Practice
-
Section 12: More Standard Library
-
Section 13: Data Structures and Algorithms in PHP
-
Section 14: More Practice Exercises
-
Section 15: More Security and Best Practices
-
Section 16: More Testing and Tooling
-
Section 17: WordPress-Style CMS Concepts
-
Section 18: Advanced OOP Practice
-
Section 19: More Web Fundamentals
-
Section 20: Database Practice
-
Section 21: PHP Manual: Array Functions
-
Section 22: PHP Manual: Date and Calendar Functions
-
Section 23: PHP Manual: Filesystem and Directory Functions
-
Section 24: PHP Manual: Filter and Var Handling
-
Section 25: PHP Manual: Math Functions
-
Section 26: PHP Manual: JSON and XML
-
Section 27: PHP Manual: Network and Stream Functions
-
Section 28: PHP Manual: Error and Exception Handling
-
Section 29: PHP Manual: Output Control and Misc
-
Section 30: PHP Manual: FTP, Zip, and Mail
-
Section 31: Modern PHP Frameworks Deep Dive
-
Section 32: PHP Design Patterns
-
Section 33: More Practice Exercises
-
Section 34: PHP Performance and Deployment
-
Section 35: More Interview Practice
-
Section 36: More PHP Standard Library
-
Section 37: PHP Concurrency and Async
-
Section 38: More Web Development Practice
-
Section 39: PHP Testing Deep Dive
-
Section 40: Composer and Package Development
-
Section 41: PHP Security Deep Dive
-
Section 42: More Practical Projects
-
Section 43: Legacy PHP Maintenance
-
Section 44: More Algorithm Practice
-
Section 45: Final Practice and Review
-
Section 46: PHP for E-Commerce Patterns
-
Section 47: PHP API Design Deep Dive
-
Section 48: PHP Caching Strategies
-
Section 49: PHP Queue and Background Jobs
-
Section 50: PHP Multi-Tenancy Patterns
-
Section 51: PHP Real-Time Features
-
Section 52: PHP CMS and Content Modeling
-
Section 53: PHP Internationalization
-
Section 54: More Framework-Specific Practice
-
Section 55: PHP Legacy Code Refactoring
-
Section 56: More Practice Projects Round 2
-
Section 57: PHP Command-Line Applications
-
Section 58: PHP and Microservices
-
Section 59: More Interview and Review Round 2
126: FTP Functions in PHP
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.
There are no comments for now.