An object-oriented FTP client for PHP.
This library is installable via Composer:
composer require brick/ftp
This library requires PHP 7.2 or later, and the ftp extension.
This library is still under development.
The current releases are numbered 0.x.y
. When a non-breaking change is introduced (adding new methods, optimizing existing code, etc.), y
is incremented.
When a breaking change is introduced, a new 0.x
version cycle is always started.
It is therefore safe to lock your project to a given release cycle, such as 0.1.*
.
If you need to upgrade to a newer release cycle, check the release history for a list of changes introduced by each further 0.x.0
version.
This repo has only 3 classes, in the Brick\Ftp
namespace:
FtpClient
is the main class to interact with an FTP serverFtpException
is thrown if any operation failsFtpFileInfo
is returned when listing directories
use Brick\Ftp\FtpClient;
use Brick\Ftp\FtpException;
try {
$client = new FtpClient();
$host = 'ftp.example.com'; // FTP server host name
$port = 21; // FTP server port
$ssl = false; // whether to open a secure SSL connection
$timeout = 90; // timeout in seconds
$username = 'ftp-user';
$password = 'p@ssw0rd';
$client->connect($host, $port, $ssl, $timeout);
$client->login($username, $password);
// You usually want to set passive mode (PASV) on; see below for an explanation
$client->setPassive(true);
} catch (FtpException $e) {
// An error occurred!
}
Only the host name is required in connect()
, the other values (port, SSL, timeout) are optional and default to the values above.
Passive mode, known as the PASV
FTP command, is a way to tell the server to open ports where the client can connect to, to upload/download a file.
By default (passive mode not enabled), the client would open a local port and request the server to connect back to the client instead.
This requires that the ports in question are not blocked by a firewall, and are directly open to the internet (no NAT, or using port forwarding). In practice, it's much easier to use passive mode as most FTP servers are already configured to support it.
As you've seen above, we wrap all calls to FtpClient
methods in a try-catch block. We won't do this in subsequent examples below for conciseness, but you should catch FtpException
in every call to FtpClient
methods, or you application will exit with "Uncaught Exception" if any error occurs.
echo $client->getWorkingDirectory(); // e.g. /home/ftp-user
$client->setWorkingDirectory('/home/ftp-user/archive');
$files = $client->listDirectory('.');
foreach ($files as $file) {
// $file is an FtpFileInfo object
echo $file->name, PHP_EOL;
}
Each value in the array returned by listDirectory()
is an FtpFileInfo
object. Depending on the capabilities of the FTP server, it may contain as little as only the file name, or additional information:
Property | Type | Nullable (optional) | Description |
---|---|---|---|
$name |
string |
No | The file name |
$isDir |
bool |
Yes | true for a directory, false for a file |
$size |
int |
Yes | The file size, in bytes |
$creationTime |
string |
Yes | The creation time |
$lastModificationTime |
string |
Yes | The last modification time |
$uniqueId |
string |
Yes | A unique identifier for the file |
If the server does not support the MLSD
command, only the file name will be available.
If the server does support this command, additional information will be available; which ones depends on the server.
As a result, you should check if a property is null
before attempting to use it, and act accordingly.
Creation time and last modification time, if available, will be in either of these formats:
YYYYMMDDHHMMSS
YYYYMMDDHHMMSS.sss
This will traverse the given directory and all of its subdirectories, and return all files found.
Just like listDirectory()
, the result is an array of FtpFileInfo
objects, but the keys of the array are the path to the file, relative to the given directory.
$files = $client->recursivelyListFilesInDirectory('.');
foreach ($files as $path => $file) {
echo $path, PHP_EOL; // a/b/c.txt
echo $file->name, PHP_EOL; // c.txt
}
Please note that this depends on the ability for the client to differentiate between files and directories. As a result, if the server does not support the MLSD
command, the result will always be an empty array.
Also, please be aware that depending on the number of files and directories, this method may take a long time to execute.
$client->rename('old/path/to/file', 'new/path/to/file');
$client->delete('path/to/file');
$client->removeDirectory('path/to/directory');
The directory must be empty, or an exception is thrown.
$size = $client->getSize('path/to/file'); // e.g. 123456
$client->download($localFile, $remoteFile);
$localFile
can be either astring
containing the local file name, or aresource
containing a file pointer$remoteFile
is the path of the file on the FTP server
This method accepts 2 additional, optional parameters:
$mode
:FTP_BINARY
(default) orFTP_ASCII
(see below for an explanation)$resumePos
: the position in the remote file to start downloading from (default0
)
FTP_BINARY
transfers the file as is, without any modification, and is the default value.FTP_ASCII
converts newlines in the file (assuming it's a text file) to the format expected by the target platform. You should usually not use this mode.
$client->upload($localFile, $remoteFile);
$localFile
can be either astring
containing the local file name, or aresource
containing a file pointer$remoteFile
is the destination path of the file on the FTP server
This method accepts 2 additional, optional parameters:
$mode
:FTP_BINARY
(default) orFTP_ASCII
(see above for an explanation)$startPos
: the position in the remote file to start uploading to (default0
)
If for any reason, you need to send a raw FTP command to the server, this method is for you. The result is an array of all lines in the response returned by the server.
Note that this method does not check if the server response contains an error code, it always returns the raw output.
$lines = $client->sendRawCommand('FEAT');
foreach ($lines as $line) {
echo $line, PHP_EOL;
}
Sample response:
211- Extensions supported:
AUTH TLS
PBSZ
PROT
CCC
SIZE
MDTM
REST STREAM
MFMT
TVFS
MLST
MLSD
UTF8
211 End.
$client->close();