Я только что выпустил 2 новые библиотеки для таких вещей в FTP / SFTP
Рекурсивное копирование файлов и папок на удаленном SFTP-сервере (если local_path заканчивается содержимым папки с косой чертой, в противном случае сама папка загружается)
Ftp::upload_dir($server, $user, $password, $local_path, $remote_path, $port = 22);
Загрузка каталога с удаленного FTP-сервера (если remote_dir заканчивается косой чертой, то загружается сама папка)
Ftp::download_dir($server, $user, $password, $remote_dir, $local_dir,
$ port = 22);
Для кода здесь он есть, но вам понадобится весь класс для зависимостей небольших утилит.
/**
* Download a directory from remote FTP server
*
* If remote_dir ends with a slash download folder content
* otherwise download folder itself
*
* @param string $server
* @param string $user
* @param string $password
* @param string $remote_dir
* @param string $local_dir
* @param int $port
*
* @return bool $downloaded
*
*/
public static function download_dir($server, $user, $password, $remote_dir, $local_dir, $port = 21)
{
$downloaded = false;
try
{
if(is_dir($local_dir) && is_writable($local_dir))
{
if(false !== $cid = Ftp::login($server, $user, $password, $port))
{
# If remote_dir do not ends with /
if(!HString::ends_with($remote_dir, '/'))
{
# Create fisrt level directory on local filesystem
$local_dir = rtrim($local_dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . basename($remote_dir);
mkdir($local_dir);
}
# Remove trailing slash
$local_dir = rtrim($local_dir, DIRECTORY_SEPARATOR);
$downloaded = Ftp::download_all($cid, $remote_dir, $local_dir);
ftp_close($cid);
}
}
else
{
throw new Exception("Local directory does not exist or is not writable", 1);
}
}
catch(Exception $e)
{
error_log("Ftp::download_dir : " . $e->getMessage());
}
return $downloaded;
}
/**
* Recursive function to download remote files
*
* @param ressource $cid
* @param string $remote_dir
* @param string $local_dir
*
* @return bool $download_all
*
*/
private static function download_all($cid, $remote_dir, $local_dir)
{
$download_all = false;
try
{
if(Ftp::is_dir($remote_dir, $cid))
{
$files = ftp_nlist($cid, $remote_dir);
if($files!==false)
{
$to_download = 0;
$downloaded = 0;
# do this for each file in the remote directory
foreach ($files as $file)
{
# To prevent an infinite loop
if ($file != "." && $file != "..")
{
$to_download++;
# do the following if it is a directory
if (Ftp::is_dir($file, $cid))// $remote_dir . DIRECTORY_SEPARATOR .
{
# Create directory on local filesystem
mkdir($local_dir . DIRECTORY_SEPARATOR . basename($file));
# Recursive part
if(Ftp::download_all($cid, $file, $local_dir . DIRECTORY_SEPARATOR . basename($file)))
{
$downloaded++;
}
}
else
{
# Download files
if(ftp_get($cid, $local_dir . DIRECTORY_SEPARATOR . basename($file), $file, FTP_BINARY))
{
$downloaded++;
}
}
}
}
# Check all files and folders have been downloaded
if($to_download===$downloaded)
{
$download_all = true;
}
}
}
}
catch(Exception $e)
{
error_log("Ftp::download_all : " . $e->getMessage());
}
return $download_all;
}