Работа с FTP в PHP

Протокол FTP – предназначен для передачи файлов на удаленный хост. В PHP функции для работы с FTP как правило всегда доступны и не требуется установка дополнительного расширения.

Как правило, при работе с FTP выполняются следующие действия:

  • Соединение с удаленным FTP-сервером (функция ftp_connect).
  • Авторизация (ftp_login).
  • Действия с файлами.
  • Закрытие соединения (ftp_close).
1

Функция ftp_nlist ($ftp_stream, $directory) получает список имен файлов и директорий в виде массива, где $ftp_stream – идентификатор соединения с FTP-сервером, $directory – путь к директории (в примере переменная пуста – это соответствует домашней директории FTP-пользователя).

// Установка соединения
$conn_id = ftp_connect('FTP сервер');
$login_result = ftp_login($conn_id, 'логин', 'пароль');
ftp_pasv($conn_id, true);

// Получить содержимое директории
$contents = ftp_nlist($conn_id, '');

print_r($contents);

// Закрытие соединения
ftp_close($conn_id);
PHP

Результат:

Array
(
    [0] => .bash_history
    [1] => .cache
    [2] => .gem
    [3] => .local
    [4] => .service
    [5] => snipp.ru
    [6] => demo
)

Получить список с расширенной информацией поможет функция ftp_rawlist().

// Установка соединения
$conn_id = ftp_connect('FTP сервер');
$login_result = ftp_login($conn_id, 'логин', 'пароль');
ftp_pasv($conn_id, true);

// Получить содержимое текущей директории
$contents = ftp_rawlist($conn_id, '.');

print_r($contents);

// Закрытие соединения
ftp_close($conn_id);
PHP

Результат:

Array
(
    [0] => -rw-------    1 10378    601          1614 Oct 02 19:05 .bash_history
    [1] => drwx------    2 10378    601          4096 Sep 30 16:53 .cache
    [2] => drwx------    2 10378    601          4096 Sep 29 20:17 .gem
    [3] => drwx------    2 10378    601          4096 Sep 29 20:17 .local
    [4] => dr-x------    4 0        0            4096 Oct 01 13:04 .service
    [5] => drwx------    3 0        0            4096 Dec 12 00:05 snipp.ru
    [6] => drwx------    2 10378    601          4096 Nov 28 09:49 demo
)

Для получения детальных данных о файлах в виде массива есть функция ftp_mlsd(), но она появилась в PHP 7 и не всегда работает, для более ранних версий PHP:

// Установка соединения
$conn_id = ftp_connect('FTP сервер');
$login_result = ftp_login($conn_id, 'логин', 'пароль');
ftp_pasv($conn_id, true);

// Получить содержимое текущей директории
$contents = ftp_rawlist($conn_id, '.');

$items = array();
foreach ($contents as $row) {
	$chunks = preg_split("/\s+/", $row);
	$items[] = array(
		'name'   => $chunks[8],
		'chmod'  => $chunks[0],
		'number' => $chunks[1],
		'user'   => $chunks[2],
		'group'  => $chunks[3],
		'size'   => $chunks[4],
		'month'  => $chunks[5],
		'day'    => $chunks[6],
		'time'   => $chunks[7],
		'type'   => $chunks[0]{0} === 'd' ? 'directory' : 'file'
	);
}

print_r($items);

// Закрытие соединения
ftp_close($conn_id);
PHP

Результат:

Array(
	[0] => Array(
		[name] => .bash_history
		[chmod] => -rw-------
		[number] => 1
		[user] => 10378
		[group] => 601
		[size] => 1614
		[month] => Oct
		[day] => 02
		[time] => 19:05
		[type] => file
	)
	[1] => Array(
		[name] => .cache
		[chmod] => drwx------
		[number] => 2
		[user] => 10378
		[group] => 601
		[size] => 4096
		[month] => Sep
		[day] => 30
		[time] => 16:53
		[type] => directory
	)
	[2] => Array(
		[name] => .gem
		[chmod] => drwx------
		[number] => 2
		[user] => 10378
		[group] => 601
		[size] => 4096
		[month] => Sep
		[day] => 29
		[time] => 20:17
		[type] => directory
	)
	[3] => Array(
		[name] => .local
		[chmod] => drwx------
		[number] => 2
		[user] => 10378
		[group] => 601
		[size] => 4096
		[month] => Sep
		[day] => 29
		[time] => 20:17
		[type] => directory
	)
	[4] => Array(
		[name] => .service
		[chmod] => dr-x------
		[number] => 4
		[user] => 0
		[group] => 0
		[size] => 4096
		[month] => Oct
		[day] => 01
		[time] => 13:04
		[type] => directory
	)
	[5] => Array(
		[name] => snipp.ru
		[chmod] => drwx------
		[number] => 3
		[user] => 0
		[group] => 0
		[size] => 4096
		[month] => Dec
		[day] => 12
		[time] => 00:05
		[type] => directory
	)
	[6] => Array(
		[name] => demo
		[chmod] => drwx------
		[number] => 2
		[user] => 10378
		[group] => 601
		[size] => 4096
		[month] => Nov
		[day] => 28
		[time] => 09:49
		[type] => directory
	)
)
2

Специальных функций для проверки существования файлов и директорий нет, поэтому можно использовать следующие варианты:

Проверить наличие файла на FTP-сервере

Функция ftp_size() возвращает «-1» если файл не найден.

// Установка соединения
$conn_id = ftp_connect('FTP сервер');
$login_result = ftp_login($conn_id, 'логин', 'пароль');
ftp_pasv($conn_id, true);

$file_size = ftp_size($conn_id, 'test.txt');
if ($file_size != -1) {
	echo 'Файл существует';
} else {
	echo 'Файл не найден';
}

// Закрытие соединения
ftp_close($conn_id);
PHP

Поверить наличие директории

Функция ftp_chdir() изменяет текущую директорию на FTP-сервере, возвращает false в случае возникновения ошибки.

// Установка соединения
$conn_id = ftp_connect('FTP сервер');
$login_result = ftp_login($conn_id, 'логин', 'пароль');
ftp_pasv($conn_id, true);

// Поверка директории
function ftp_directory_exists($conn_id, $dir)
{
	$origin = ftp_pwd($conn_id);
	if (@ftp_chdir($conn_id, $dir)) {
		ftp_chdir($conn_id, $origin);   
		return true;
	}

	return false;
}

if (ftp_directory_exists($conn_id, 'path')){
	echo 'Директория существует';
} else {
	echo 'Директория не существует';
}

// Закрытие соединения
ftp_close($conn_id);
PHP
3

Получить размер файла

Функция ftp_size() возвращает размер файла в байтах.

// Установка соединения
$conn_id = ftp_connect('FTP сервер');
$login_result = ftp_login($conn_id, 'логин', 'пароль');
ftp_pasv($conn_id, true);

echo ftp_size($conn_id, 'test.txt'); // 38490

// Закрытие соединения
ftp_close($conn_id);
PHP

Получить размер FTP директории

// Установка соединения
$conn_id = ftp_connect('FTP сервер');
$login_result = ftp_login($conn_id, 'логин', 'пароль');
ftp_pasv($conn_id, true);
 
// Получить размер директории
function ftp_size_dir($conn_id, $directory)
{ 
	$size = 0;
	$origin = ftp_pwd($conn_id);
	if (ftp_chdir($conn_id, $directory)){
		ftp_chdir($conn_id, $origin);  
		$filelist = @ftp_nlist($conn_id, $directory); 
		foreach($filelist as $file) {
			$size += ftp_size_dir($conn_id, $file); 
		} 
	} else {
		$size += ftp_size($conn_id, $directory); 
	}
	
	return $size;
} 

echo ftp_size_dir($conn_id, 'demo'); // 769588

// Закрытие соединения
ftp_close($conn_id);
PHP

К полученному результату можно применить функцию для конвертации байтов в килобайты и мегабайты.

4
// Установка соединения
$conn_id = ftp_connect('FTP сервер');
$login_result = ftp_login($conn_id, 'логин', 'пароль');
ftp_pasv($conn_id, true);

echo ftp_mdtm($conn_id, 'test.txt'); // 1605347682

// Закрытие соединения
ftp_close($conn_id);
PHP
5
// Установка соединения
$conn_id = ftp_connect('FTP сервер');
$login_result = ftp_login($conn_id, 'логин', 'пароль');
ftp_pasv($conn_id, true);

if (ftp_chmod($conn_id, 0777, 'test.txt') !== false) {
	echo 'Права доступа к файлу успешно изменены';
} else {
	echo 'Не удалось изменить права доступа к файлу';
}

// Закрытие соединения
ftp_close($conn_id);
PHP
6
// Установка соединения
$conn_id = ftp_connect('FTP сервер');
$login_result = ftp_login($conn_id, 'логин', 'пароль');
ftp_pasv($conn_id, true);

// Создание файла на сервере
$text = 'Содержимое файла file.txt';
$file = fopen('php://temp', 'r+');
fwrite($file, $text);
rewind($file);

if (ftp_fput($conn_id, 'file.txt', $file, FTP_ASCII)) {
	echo 'Файл создан';
} else {
	echo 'Не удалось создать файл';
}
 
// Закрытие соединения
ftp_close($conn_id);
PHP
// Установка соединения
$conn_id = ftp_connect('FTP сервер');
$login_result = ftp_login($conn_id, 'логин', 'пароль');
ftp_pasv($conn_id, true);

// Cоздания директории
if (ftp_mkdir($conn_id, 'new_patch')) {
	echo 'Директория создана';
} else {
	echo 'Не удалось создать директорию ';
}
 
// Закрытие соединения
ftp_close($conn_id);
PHP
7
// Установка соединения
$conn_id = ftp_connect('FTP сервер');
$login_result = ftp_login($conn_id, 'логин', 'пароль');
ftp_pasv($conn_id, true);

// Переименовать файл и папку
if (ftp_rename ($conn_id, 'test.txt', 'test_1.txt')) {
	echo 'Файл переименован';
} else {
	echo 'Не удалось переименовать файл';
}

// Закрытие соединения
ftp_close($conn_id);
PHP
8
// Установка соединения
$conn_id = ftp_connect('FTP сервер');
$login_result = ftp_login($conn_id, 'логин', 'пароль');
ftp_pasv($conn_id, true);

// Загрузка файла 
$file = __DIR__ . '/test.txt';

if (ftp_put($conn_id, basename($file), $file, FTP_ASCII)) {
	echo 'Файл успешно загружен';
} else {
	echo 'Не удалось загрузить файл';
}

// Закрытие соединения
ftp_close($conn_id);
PHP
// Установка соединения
$conn_id = ftp_connect('FTP сервер');
$login_result = ftp_login($conn_id, 'логин', 'пароль');
ftp_pasv($conn_id, true);

// Закачать папку с файлами
function ftp_upload_dir($conn_id, $src, $drc) {
	@ftp_mkdir($conn_id, $drc);

	$objs = scandir($src);
	foreach($objs as $obj) {
		if ($obj == '.' || $obj == '..') {
			continue;
		} elseif (is_dir($src . '/' . $obj)) {
			ftp_upload_dir($conn_id, $src . '/' . $obj, $drc . '/' . $obj);
		} else {
			@ftp_chdir($conn_id, $drc . '/' . $obj);
			ftp_put($conn_id, $drc . '/' . $obj, $src . '/' . $obj, FTP_BINARY);
		}
	}
}

ftp_upload_dir($conn_id, __DIR__ . '/trash', 'trash');

// Закрытие соединения
ftp_close($conn_id);
PHP
9
// Установка соединения
$conn_id = ftp_connect('FTP сервер');
$login_result = ftp_login($conn_id, 'логин', 'пароль');
ftp_pasv($conn_id, true);
 
// Прочитать файл в переменную
$file = 'test.txt';
$handle = fopen('php://temp', 'r+');

if (ftp_fget($conn_id, $handle, $file, FTP_BINARY, 0)) {
	$fstats = fstat($handle);
	fseek($handle, 0);
	$contents = fread($handle, $fstats['size']); 
	echo $contents;
} else {
	echo 'Произошла ошибка при чтении файла';
}

// Закрытие файла и соединения
fclose($handle);
ftp_close($conn_id);
PHP
10
// Установка соединения
$conn_id = ftp_connect('FTP сервер');
$login_result = ftp_login($conn_id, 'логин', 'пароль');
ftp_pasv($conn_id, true);
 
// Скачать файл
$file = 'test.txt';
$handle = fopen(__DIR__ . '/' . $file, 'w');

if (ftp_fget($conn_id, $handle, $file, FTP_ASCII, 0)) {
	echo 'Файл успешно скачен';
} else {
	echo 'Ошибка';
}

// Закрытие файла и соединения
fclose($handle);
ftp_close($conn_id);
PHP
// Установка соединения
$conn_id = ftp_connect('FTP сервер');
$login_result = ftp_login($conn_id, 'логин', 'пароль');
ftp_pasv($conn_id, true);
 
// Скачать папку с файлами
function ftp_download_dir($conn_id, $src, $drc) {
	if (ftp_chdir($conn_id, $src) === FALSE) {
		return;
	}
	if (!(is_dir($drc))) {
		mkdir($drc);
	}
	chdir($drc);

	$contents = ftp_nlist($conn_id, '.');
	foreach ($contents as $file) {
		if ($file == '.' || $file == '..') {
			continue;
		}

		if (@ftp_chdir($conn_id, $file)) {
			ftp_chdir($conn_id, "..");
			ftp_download_dir($conn_id, $file, $drc . '/' . $file);
		} else {
			ftp_get($conn_id, $file, $file, FTP_BINARY);
		}
	}

	ftp_chdir($conn_id, '..');
	chdir('..');
}

ftp_download_dir($conn_id, 'trash', __DIR__ . '/trash');

// Закрытие соединения
ftp_close($conn_id);
PHP
11

Вожно! Перед выполнением следующих функций сделате полный бэкап т.к. при указании  неправельнх путей к директориям могут удалиться все файлы на сервере.

// Установка соединения
$conn_id = ftp_connect('FTP сервер');
$login_result = ftp_login($conn_id, 'логин', 'пароль');
ftp_pasv($conn_id, true);

// Удалить файл с FTP-сервера
if (ftp_delete($conn_id, 'demo.txt')) {
	echo 'Файл удален';
} else {
	echo 'Не удалось файл';
}

// Закрытие соединения
ftp_close($conn_id);
PHP
// Установка соединения
$conn_id = ftp_connect('FTP сервер');
$login_result = ftp_login($conn_id, 'логин', 'пароль');
ftp_pasv($conn_id, true);

// Удаление содержимого директории
function ftp_clear_dir($conn_id, $directory, $remove_parent = false)
{ 
	if (!(@ftp_rmdir($conn_id, $directory) || @ftp_delete($conn_id, $directory))) { 
		$filelist = @ftp_nlist($conn_id, $directory); 
		foreach($filelist as $file) {
			ftp_clear_dir($conn_id, $file, true); 
		} 
		if ($remove_parent == true) {
			ftp_clear_dir($conn_id, $directory, true); 		
		}
	} 
} 

ftp_clear_dir($conn_id, 'trash');

// Закрытие соединения
ftp_close($conn_id);
PHP
// Установка соединения
$conn_id = ftp_connect('FTP сервер');
$login_result = ftp_login($conn_id, 'логин', 'пароль');
ftp_pasv($conn_id, true);
 
// Удаление директории со всем содержимым
function ftp_remove_dir($conn_id, $directory)
{ 
	if (!(@ftp_rmdir($conn_id, $directory) || @ftp_delete($conn_id, $directory))) { 
		$filelist = @ftp_nlist($conn_id, $directory); 
		foreach($filelist as $file) {
			ftp_remove_dir($conn_id, $file); 
		} 
		ftp_remove_dir($conn_id, $directory); 
	} 
} 
 
ftp_remove_dir($conn_id, 'trash');
 
// Закрытие соединения
ftp_close($conn_id);
PHP
14.12.2020, обновлено 15.04.2022
18078
Предыдущая запись Примеры использования PuTTY
Следующая запись Figma – советы верстальщику

Комментарии 3

Синул Ежемэкю Синул Ежемэкю
10 июня 2021 в 16:35
Спасибо за статью! Потыкал рекламу;)
Gennady GA Gennady GA
29 октября 2022 в 10:04
Спасибо за инфо, рекламу потыкал!)))
chokolad chokolad
22 июня 2023 в 10:26
Слушайте, а как в таком случае безопасно хранить эти данные от ФТП на сайте?

, чтобы добавить комментарий.

Другие публикации

Поиск файлов в PHP
Для поиска файлов на сервере хорошо подходит функция glob(), которая возвращает список файлов по заданной маске, например...
23380
+1
Работа с директориями в PHP
Набор PHP функций для работы с директориями, получение списка файлов в папке, копирование и удаление содержимого папок.
28728
-1
Массив $_SERVER
Описание значений глобального массива $_SERVER с примерами.
51347
+3
Генерация счета на оплату PDF PHP
С помощью расширения dompdf можно легко сформировать PDF файл. По сути, dompdf - это конвертер HTML в PDF который...
64774
+33
Поиск похожих текстов в базе данных MySQL + PHP
Один из вариантов поиска похожих статей в базе данных основан на схождении слов в двух текстах.
7083
+7
Преобразование цветов в PHP
Несколько примеров как перевести цвета из HEX в RGB и обратно с помощью PHP.
15729
-1