PHP FTP client

PHP provides complete support for FTP and FTPS (FTP over SSL) protocols via a set of functions (FTP extension). These functions may be used in PHP scripts to develop FTP clients to interact with a remote FTP server.

This tutorial presents how to use the FTP PHP API.

FTP vs FTPS

FTP is by definition an insecure protocol. When an FTP client communicates with a remote FTP server, all of the network traffic is sent unencrypted, even the authentication credentials.

To solve the security issues of FTP, FTPS was developed as an extension to FTP. With FTPS, the client and the server communicate using the same protocol FTP but over a secure SSL channel.

The PHP FTP functions are used to work with both.

Active mode vs passive mode

Using the FTP protocol, the client and the server may communicate in two modes: active and passive.

With active mode, when the client connects to the FTP server and requests data, the server opens another connection from its port 20 to the IP address of the client on a random unprivileged port (greater than 1024) specified by this later and delivers the response data using this second connection. Because client-side firewalls often deny incoming connections, using active mode is generally not advised.

When the FTP client connects to the FTP server and indicates it wants to access the data in passive mode, the server provides another random unprivileged port (greater than 1024) for the client to connect to and download the requested information. The passive mode resolves the issue of client-side firewall but complicates the administration of the server-side firewall.

PHP defaults to using FTP in active mode, which is almost never used anymore since the creation of firewalls. The function ftp_pasv() should always be used to switch to passive mode when downloading or uploading files.

ftp_pasv ( resource $ftp_stream , bool $pasv ) : bool

The later sections provide several examples.

Warning messages

Some of the FTP functions throw PHP warnings when the operation fails (failed login operation for example). This is generally wanted only in development environments but not in production.

To suppress PHP warning messages, the error_reporting() function may be used like the following:

error_reporting(E_ERROR | E_PARSE);

Connection and authentication

FTP is a client/server protocol. An FTP client opens a TCP connection to a remote FTP server, authenticates via a username and password then starts performing file operations (FTP commands). Anonymous authentication may be permitted by the server.

The function ftp_connect() is used to open a connection to a remote FTP server:

ftp_connect ( string $host [, int $port = 21 [, int $timeout = 90 ]] ) : resource

It accepts the following arguments:

  • $host: the FTP server hostname or IP address
  • $port: an optional server TCP port number. It defaults to 21
  • $timeout: an optional timeout in seconds of network operations. It default to 90 seconds

It returns a connection identifier (Stream resource) that will be used by the rest of the functions to communicate with the FTP server. It returns FALSE on error.

If the server is configured to use SSL (FTPS), the connection should be opened using the function ftp_ssl_connect() instead:

ftp_ssl_connect ( string $host [, int $port = 21 [, int $timeout = 90 ]] ) : resource

It has the same semantics and accepts the same arguments as the function ftp_connect().

After the creation of the connection stream with ftp_connect() or ftp_ssl_connect(), the authentication may be performed using the function ftp_login():

ftp_login ( resource $ftp_stream , string $username , string $password ) : bool

It accepts the three arguments: the connection identifier, the username and the password. It returns TRUE on success or FALSE on failure.

The function ftp_close() is used at the end to close the communication with the remote server and release resources. It accepts one argument, the connection identifier.

The following example presents how to connect and authenticate to an FTP server:

<?php
$server = "localhost";
$username = "ftp_user";
$password = "1234";

// Connection
$con = ftp_connect($server);
if($con == false){
    echo "Could not connect to FTP server\n";
    die();
}

// Authentication
if(ftp_login($con, $username, $password) == false){
    echo "Authentication failed\n";
    die();
}

echo "Connection/authentication OK";

ftp_close($con);

Changing the working directory

When first connected to the FTP server, the current working directory is set to the user’s home one. To change to a different directory, the function ftp_chdir() is used:

ftp_chdir ( resource $ftp_stream , string $directory ) : bool

It accepts two arguments: the connection identifier and the path to the new directory. It returns TRUE on success (the directory exists and the user has access rights) or FALSE on failure.

The following example presents how to change the current working directory:

<?php
$server = "localhost";
$username = "ftp_user";
$password = "1234";
$directory_path = "my_directory";

// Connection
$con = ftp_connect($server);
if($con == false){
    echo "Could not connect to FTP server\n";
    die();
}

// Authentication
if(ftp_login($con, $username, $password) == false){
    echo "Authentication failed\n";
    die();
}

// Change the current working directory
if(ftp_chdir($con, $directory_path) == false){
    echo "The directory $directory_path does not exist\n";
    echo "Or the user has not permission to access it\n";
    die();
}

ftp_close($con);

Creating a directory

To create a new directory on a remote FTP server, the function ftp_mkdir() is used:

ftp_mkdir ( resource $ftp_stream , string $directory ) : string

It accepts two arguments: the connection identifier and the name of the directory to create. It returns the name of the newly-created directory on success or FALSE on error. The directory is created in the current working directory. To create a directory inside a subdirectory, the current working directory should be changed to this later first.

The following example presents how to create the directory my_directory2 inside the directory my_directory1:

<?php
$server = "localhost";
$username = "ftp_user";
$password = "1234";
$directory1 = "my_directory1";
$directory2 = "my_directory2";

// Connection
$con = ftp_connect($server);
if($con == false){
    echo "Could not connect to FTP server\n";
    die();
}

// Authentication
if(ftp_login($con, $username, $password) == false){
    echo "Authentication failed\n";
    die();
}

// Change the current working directory
if(ftp_chdir($con, $directory1) == false){
    echo "The directory $directory1 does not exist\n";
    die();
}

// Create the directory
if(ftp_mkdir($con, $directory2) == false){
    echo "Could not create the directory $directory2\n";
    die();
}

echo "The directory $directory1/$directory2 is created\n";

ftp_close($con);

Listing a remote directory content

To list the content of a remote directory, the function ftp_nlist() is used:

ftp_nlist ( resource $ftp_stream , string $directory ) : array

It accepts two arguments: the connection identifier and the path of the remote directory. It returns an array of file names.

The following example presents how to list the content of a remote directory:

<?php
$server = "localhost";
$username = "ftp_user";
$password = "1234";
$directory_path = "my_directory";

// Connection
$con = ftp_connect($server);
if($con == false){
    echo "Could not connect to FTP server\n";
    die();
}

// Authentication
if(ftp_login($con, $username, $password) == false){
    echo "Authentication failed\n";
    die();
}

// List the directory content
foreach(ftp_nlist($con, $directory_path) as $filename){
    echo "$filename\n";
}

ftp_close($con);

Downloading a remote file

To download a remote file, the function ftp_get() is used:

ftp_get ( resource $ftp_stream , string $local_file , string $remote_file [, int $mode = FTP_BINARY [, int $resumepos = 0 ]] ) : bool

It accepts the following arguments:

  • $ftp_stream: the connection identifier
  • $local_file: the local file to download the file to. It will be overwritten if it already exists
  • $remote_file: the remote file to download from
  • $mode: specifies whether the download is done if text or binary mode. In binary mode the file is preserved as it is. In text mode some modifications may be done on the file such as changing the end of line indicator to match the one of the current OS. It is recommended to keep it in binary mode unless there is a specific requirement. In recent versions of PHP it is optional and default to binary mode. In older versions it is mandatory. It must be either FTP_ASCII or FTP_BINARY
  • $resumepos: an optional integer that is used to resume download from a specific position. It default to zero to start a new download operation

 It returns TRUE on success or FALSE on failure.

The following example presents how to download a file from an FTP server:

<?php
$server = "localhost";
$username = "ftp_user";
$password = "1234";
$local_file = "my_file.txt";
$remote_file = "my_directory/my_file.txt";

// Connection
$con = ftp_connect($server);
if($con == false){
    echo "Could not connect to FTP server\n";
    die();
}

// Authentication
if(ftp_login($con, $username, $password) == false){
    echo "Authentication failed\n";
    die();
}

// Switch to passive mode
ftp_pasv ( $con, true );

// Download the file
if(ftp_get($con, $local_file, $remote_file, FTP_BINARY))
    echo "File downloaded successfully\n";
else
    echo "File download error\n";

ftp_close($con);

Uploading a local file/directory

To upload a local file to a remote FTP server, the function ftp_put() is used:

ftp_put ( resource $ftp_stream , string $remote_file , string $local_file [, int $mode = FTP_BINARY [, int $startpos = 0 ]] ) : bool

It accepts the following arguments:

  • $ftp_stream: the connection identifier
  • $remote_file: the remote file location. It will be overwritten if it already exists
  • $local_file: the local file to upload.
  • $mode: specifies whether the download is done if text or binary mode. In binary mode the file is preserved as it is. In text mode some modifications may be done on the file such as changing the end of line indicator to match the one of the current OS. It is recommended to keep it in binary mode unless there is a specific requirement. In recent versions of PHP it is optional and default to binary mode. In older versions it is mandatory. It must be either FTP_ASCII or FTP_BINARY
  • $resumepos: an integer that is used to resume upload from a specific position. It default to zero to start a new upload operation

 It returns TRUE on success or FALSE on failure.

The following example presents how to upload a local file to an FTP server:

<?php
$server = "localhost";
$username = "ftp_user";
$password = "1234";
$local_file = "my_file.txt";
$remote_file = "my_directory/my_file.txt";

// Connection
$con = ftp_connect($server);
if($con == false){
    echo "Could not connect to FTP server\n";
    die();
}

// Authentication
if(ftp_login($con, $username, $password) == false){
    echo "Authentication failed\n";
    die();
}

// Switch to passive mode
ftp_pasv ( $con, true );

// Upload the file
if(ftp_put($con, $remote_file, $local_file, FTP_BINARY))
    echo "File uploaded successfully\n";
else
    echo "File upload error\n";

ftp_close($con);

Deleting a file or a directory

To delete a file the function ftp_delete() is used:

ftp_delete ( resource $ftp_stream , string $path ) : bool

To delete a directory, the function ftp_rmdir() is used. The directory should be empty:

ftp_rmdir ( resource $ftp_stream , string $directory ) : bool

They both accept two arguments, the connection identifier and the file or directory to delete. They return TRUE on success or FALSE on failure.

The following example presents how to delete a file and a directory:

<?php
$server = "localhost";
$username = "ftp_user";
$password = "1234";
$file = "my_directory/my_file.txt";
$directory = "my_directory";

// Connection
$con = ftp_connect($server);
if($con == false){
    echo "Could not connect to FTP server\n";
    die();
}

// Authentication
if(ftp_login($con, $username, $password) == false){
    echo "Authentication failed\n";
    die();
}

// Delete the file
if(ftp_delete($con, $file) == false){
    echo "Could not delete the file $file\n";
    die();
}

// Delete the directory
if(ftp_rmdir($con, $directory) == false){
    echo "Could not delete the directory $directory\n";
    die();
}

ftp_close($con);

Setting permissions

FTP uses the traditional Unix permissions scheme (Read/Write/Execute). To set permissions on a file or directory on a remote FTP server, the function ftp_chmod() is used:

ftp_chmod ( resource $ftp_stream , int $mode , string $filename ) : int

It accepts three arguments: the connection identifier, the new permissions expressed as an octal number  and the remote file name.

It returns TRUE on success or FALSE on failure.

The following example presents how to set permissions on a remote file:

<?php
$server = "localhost";
$username = "ftp_user";
$password = "1234";
$file = "my_directory/my_file.txt";

// Connection
$con = ftp_connect($server);
if($con == false){
    echo "Could not connect to FTP server\n";
    die();
}

// Authentication
if(ftp_login($con, $username, $password) == false){
    echo "Authentication failed\n";
    die();
}

// Change permissions to 660
if(ftp_chmod($con, 0660, $file) == false){
    echo "Could not set permissions of file $file\n";
    die();
}

ftp_close($con);

Renaming a file

To rename a file, the function ftp_rename() is used:

ftp_rename ( resource $ftp_stream , string $oldname , string $newname ) : bool

It accepts three arguments: the connection identifier, the old file name, and the new one.

It returns TRUE on success or FALSE on failure.

<?php
$server = "localhost";
$username = "ftp_user";
$password = "1234";
$file = "my_file.txt";
$new_name = "my_new_file.txt";

// Connection
$con = ftp_connect($server);
if($con == false){
    echo "Could not connect to FTP server\n";
    die();
}

// Authentication
if(ftp_login($con, $username, $password) == false){
    echo "Authentication failed\n";
    die();
}

// Rename the file
if(ftp_rename($con, $file, $new_name) == false){
    echo "Could not rename the file $file\n";
    die();
}

ftp_close($con);

References

The FTP extension reference: https://www.php.net/manual/en/book.ftp.php