This guide is for developers looking to understand and use SFTP (a secure protocol for file transfers) with PHP. The focus will be on the PHP Secure Communications Library (phpseclib), a robust library that provides an easy-to-use interface for secure communications in PHP. It supports a broad range of cryptographic operations, including SSH2 (SFTP), RSA, and symmetric encryption.
Here's an article
detailing why we prefer to use phpseclib as our PHP SFTP library.
Basically, it's an SFTP client written in pure PHP. In case you don't want to spend your time managing SFTP servers,
SFTPCloud
can do this for you on autopilot.
Getting Started with phpseclib
Before we go further into the details of using phpseclib for SFTP, let's ensure it's installed and ready to use. The recommended way to install phpseclib is through Composer, a dependency management tool for PHP. If you haven't installed Composer yet, you can download it from the official website.
Once Composer is installed, navigate to your project directory and install phpseclib by running the following command:
composer require phpseclib/phpseclib:~3.0
Connecting to a remote server via SFTP
With phpseclib installed, we can now create an SFTP connection to a remote server. To connect to an SFTP server using phpseclib as the SFTP client, you'll need the server's hostname (or IP address), a valid username, and password or SSH key pair. Here's a basic example of connecting using a username and password:
<?php
require_once('vendor/autoload.php');
use phpseclib3\Net\SFTP;
$host = 'eu-central-1.sftpcloud.io';
$user = 'my-sftp-user';
$password = 'my-sftp-user-password';
$sftp = new SFTP($host);
if (!$sftp->login($user, $password)) {
throw new \Exception('Could not initialize SFTP subsystem.');
}
echo 'Login successful';
This script creates a new SFTP object and attempts to log in. If the login is unsuccessful, it throws an exception. If it's successful, it displays a
Login successful
message. Because there are multiple SFTP versions, the connection is made using the default version. More details about changing the version can be found
here
or at the bottom of the article.
SFTP file operations with PHP
The primary purpose of SFTP is to perform file operations on a remote server securely. Let's discuss some of the most common operations and how to perform them using PHP.
Uploading a file
To upload a local file to the server, use the
put
method:
<?php
// ...
$file_to_upload = '/path/to/local/file.txt';
$remote_file_path = '/path/to/remote/directory/file.txt';
$sftp->put($remote_file_path, $file_to_upload, SFTP::SOURCE_LOCAL_FILE);
This example uploads a local file to a remote directory. The
put
method takes three parameters: the remote file path, the local file path, and the mode of the source, which in this case is
SFTP::SOURCE_LOCAL_FILE
.
If you want to upload a string instead of a file, you can do it by using
SFTP::SOURCE_STRING
as mode. Here is an example:
<?php
// ...
$file_contents = 'This string will be uploaded';
$remote_file_path = '/path/to/remote/directory/file.txt';
$sftp->put($remote_file_path, $file_coontents, SFTP::SOURCE_STRING);
Downloading a file
Downloading a file is as simple as uploading. Use the
get
method, which accepts two parameters:
$remote_file_path
: The path to the file on the SFTP server that you want to download. This should include the full path to the file, including the filename and its extension.
$local_file_path
: The path on the local system where the downloaded file should be saved. This should also include the filename and extension that you want for the downloaded file.
<?php
// ...
$remote_file_path = '/path/to/remote/file.txt';
$local_file_path = '/path/to/local/directory/file.txt';
$sftp->get($remote_file_path, $local_file_path);
Here are a few important points to consider when using the
get
method:
Permissions
: The SFTP user (i.e., the username you used when creating the
SFTP
object and calling
login
) must have read permissions for the file you want to download. If the user does not have these permissions, the
get
operation will fail.
File Existence
: If the file you are trying to download does not exist on the SFTP server, the
get
method will return
false
.
Local Directory
: The local directory where you want to save the file must exist, and your PHP script must have write permissions to that directory. If the directory does not exist or the script does not have the necessary permissions, the
get
operation will fail.
Deleting files
To delete a file, use the
delete
method. The method accepts one parameter: the path to the file you want to delete. This should be the full path to the file on the SFTP server.
<?php
// ...
$file_to_delete = '/path/to/remote/file.txt';
$sftp->delete($file_to_delete);
Here are a few important considerations when using the
delete
method:
Paths
: The path should include the filename and, if applicable, the directory in which the file is located. If the file is in the root directory, you would include the filename only. If the file is in a subdirectory, you should include the directory path as well.
Permissions
: The SFTP user (i.e., the username you used when creating the
SFTP
object and calling
login
) needs to have the appropriate permissions to delete files in the directory where the file is located. If the user does not have sufficient permissions, the
delete
operation will fail.
Non-existent Files
: If you attempt to delete a file that does not exist, the
delete
method will return
false
, and no exception will be thrown.
Renaming a file
In your daily operations, you may need to rename a file on your SFTP server. The
rename
method provided by the phpseclib library is designed for this purpose. This function accepts two parameters: the current name (path included) of the file and the new name (with path) that you want to give to the file. Here's an example:
<?php
// ...
$old_name = '/path/to/remote/file.txt';
$new_name = '/path/to/remote/newfile.txt';
$sftp->rename($old_name, $new_name);
It's important to note a few things about this method:
Paths
: Both the old and new filenames should include the full path to the file. If the file is in the root directory, you would include the filename only. If the file is in a subdirectory, you should include the directory path.
Permissions
: The user you're logged in as (i.e., the username you used when creating the
SFTP
object and calling
login
) should have the appropriate permissions to rename files in the directory where the file is located.
Existing Files
: If a file with the new name already exists at the destination, the
rename
operation will overwrite it. Be careful to ensure that you don't unintentionally overwrite important files.
Error Handling
: Like all operations that interact with external systems, renaming operations can fail for various reasons, such as network issues or file permission problems. It's important to handle these potential errors gracefully in your code. You can wrap the operation in a
try/catch
block to catch any exceptions that might be thrown.
Here is an example of renaming a file with error handling:
<?php
// ...
$old_name = '/path/to/remote/file.txt';
$new_name = '/path/to/remote/newfile.txt';
try {
$sftp->rename($old_name, $new_name);
} catch (\Exception $e) {
echo 'Error renaming file: ' . $e->getMessage();
}
Listing all the files and directories
An essential aspect of managing your SFTP server is being able to list all the files and directories in a particular location. The phpseclib library provides the
nlist
and
rawlist
methods for this purpose.
Let's start with the
nlist
method, which provides a simple array of filenames.
<?php
// ...
$directory = '/path/to/remote/directory';
$file_list = $sftp->nlist($directory);
In this example,
nlist
is used to retrieve an array of filenames in the directory
/path/to/remote/directory
on the SFTP server. The
$directory
parameter should be the path to the directory you want to list files from.
The
nlist
method is straightforward, but it provides limited information: only filenames. If you need more detailed information about the files, such as their sizes, modification times, or permissions, you should use the
rawlist
method.
Here's an example using
rawlist
:
<?php
// ...
$directory = '/path/to/remote/directory';
$file_list = $sftp->rawlist($directory);
The
rawlist
method returns an associative array for each file, where the key is the filename and the value is another associative array with detailed information about the file. This detailed array includes fields such as
type
(file type),
size
(file size, in bytes), and
mtime
(last modification time).
Consider these points when using these methods:
Permissions
: The SFTP user (i.e., the username you used when creating the
SFTP
object and calling
login
) must have read permissions for the directory you want to list files from. If the user does not have these permissions, the operation will fail.
Existing Directory
: If the directory specified does not exist on the SFTP server, both
nlist
and
rawlist
will return false.
Error Handling
: As always, handle potential errors gracefully in your code. You can check the return value of these methods to see if the operation was successful.
<?php
// ...
$directory = '/path/to/remote/directory';
try {
$file_list = $sftp->nlist($directory);
if ($file_list === false) {
throw new Exception('Error listing files in directory: ' . $directory);
}
print_r($file_list);
} catch (\Exception $e) {
echo $e->getMessage();
}
There are also other things that you may consider, such as ordering the listed files using a valid sort parameter. For more details, have a look at our dedicated article about
listing the files of an SFTP server in PHP
.
Changing directories
Sometimes, you might need to change the current working directory on the SFTP server. For example, you might need to navigate to a specific directory to upload or download files, or perform operations like listing files or creating new directories. phpseclib's
SFTP
class provides a method named
chdir
(short for "change directory") for this purpose. Here's how to use
chdir
:
<?php
// ...
$directory = '/path/to/remote/directory';
$sftp->chdir($directory);
In the example above, we're using the
chdir
method to change the current directory on the SFTP server to
/path/to/remote/directory
.
The
chdir
method takes one argument: the path to the directory you want to change to. This should be the full path of the directory on the SFTP server.
When using
chdir
, keep in mind the following points:
Paths
: Ensure to provide the correct path to the directory. If the specified directory does not exist, the
chdir
operation will fail.
Permissions
: The SFTP user (i.e., the username you used when creating the
SFTP
object and calling
login
) needs to have the appropriate permissions to access the directory. If the user does not have these permissions, the
chdir
operation will fail.
You can also check the current directory using the
pwd
method:
<?php
// ...
echo $sftp->pwd(); // Outputs the current directory
Changing SFTP versions
SFTP has seven versions, defined from v0 to v6. OpenSSH has support only for v3, but there are SFTP servers that support multiple, or even all versions. If you are using phpseclib ≥ 3.0.11, you can set the preferred version by calling
setPreferredVersion($versionNumber)
, where
$versionNumber
is a variable holding the version as an integer. In case you want to use version 6, you have to call
setPreferredVersion(6)
. You can see what versions the server supports by calling the
getSupportedVersions()
method.