ftp_mlsd()
PHP ftp_mlsd(): получение структурированного списка FTP-директории. Синтаксис, возвращаемые значения, примеры и обработка ошибок.
Что такое ftp_mlsd()?
ftp_mlsd() — это встроенная функция PHP (доступна начиная с PHP 7.2), которая выводит содержимое директории на FTP-сервере с помощью команды FTP MLSD. В отличие от более старых функций листинга, она возвращает структурированный, машиночитаемый результат: вместо необработанного текстового блока, который нужно разбирать самостоятельно, вы получаете array записей, где каждый файл или директория содержит именованные атрибуты — тип, размер и время изменения.
Это важно, потому что листинги директорий FTP-серверов печально известны своей непоследовательностью — ftp_rawlist() возвращает строки, формат которых зависит от операционной системы сервера. Команда MLSD была добавлена в протокол FTP (RFC 3659) именно для стандартизации этого, и ftp_mlsd() предоставляет к ней прямой доступ.
Используйте ftp_mlsd(), когда вам нужно:
- Перечислить файлы и знать размер, тип или временную метку каждого из них.
- Надёжно отличать директории от файлов (атрибут
typeделает это за вас). - Избежать хрупкого разбора строк, который навязывает
ftp_rawlist().
Если вам нужен лишь плоский список имён файлов, ftp_nlist() проще. Если необходимо поддерживать серверы до версии 7.2 или серверы без поддержки MLSD, используйте ftp_rawlist().
Синтаксис ftp_mlsd()
ftp_mlsd(FTP\Connection $ftp, string $directory): array|falseФункция принимает два обязательных параметра:
| Параметр | Описание |
|---|---|
$ftp | Идентификатор FTP-соединения, возвращаемый ftp_connect() (или ftp_ssl_connect()). |
$directory | Путь к директории для листинга, например /public_html или . для текущей директории. |
Оба параметра обязательны. Команда MLSD всегда работает с явным путём — передавайте ., если хотите получить листинг текущей директории.
При успехе функция возвращает array записей, при неудаче — false (например, если путь не существует или сервер не поддерживает MLSD).
Что возвращает ftp_mlsd()
Каждый элемент возвращаемого array — это ассоциативный array, описывающий одну запись. Конкретные ключи зависят от того, что сообщает сервер, но наиболее распространённые из них:
| Ключ | Значение |
|---|---|
name | Имя файла или директории. |
type | Тип записи: file, dir, cdir (текущая директория, .) или pdir (родительская директория, ..). |
size | Размер в байтах (обычно присутствует только для файлов). |
modify | Временная метка последнего изменения в формате YYYYMMDDHHMMSS. |
perms | Строка прав доступа, сообщаемая сервером. |
unique | Присваиваемый сервером идентификатор, уникальный для каждого файла. |
Структура одной записи выглядит следующим образом:
[
'name' => 'report.pdf',
'type' => 'file',
'size' => '20480',
'modify' => '20240115093000', // 2024-01-15 09:30:00
'perms' => 'adfr',
]Использование ftp_mlsd()
Перед тем как получить листинг, необходимо подключиться с помощью ftp_connect() и пройти аутентификацию с помощью ftp_login(). Полный рабочий процесс выглядит так:
<?php
// 1. Open a connection
$ftp = ftp_connect('ftp.example.com');
// 2. Authenticate
ftp_login($ftp, 'username', 'password');
// 3. Switch to passive mode (recommended behind firewalls/NAT)
ftp_pasv($ftp, true);
// 4. Get a structured listing of the directory
$entries = ftp_mlsd($ftp, '/public_html');
// 5. Always close the connection when done
ftp_close($ftp);Итерация по списку
Настоящая ценность ftp_mlsd() — структурированные данные. Здесь мы выводим каждый файл с удобочитаемым размером и пропускаем псевдозаписи . и ..:
<?php
$entries = ftp_mlsd($ftp, '.');
foreach ($entries as $entry) {
// Skip the current-dir and parent-dir markers
if (in_array($entry['type'], ['cdir', 'pdir'], true)) {
continue;
}
if ($entry['type'] === 'dir') {
echo "[DIR] {$entry['name']}\n";
} else {
$kb = round($entry['size'] / 1024, 1);
echo "[FILE] {$entry['name']} ({$kb} KB)\n";
}
}Поле modify содержит 14-значную временную метку. Вы можете преобразовать её в нормальную дату с помощью DateTime:
<?php
$modified = DateTime::createFromFormat('YmdHis', $entry['modify']);
echo $modified->format('Y-m-d H:i:s');Обработка ошибок в ftp_mlsd()
ftp_mlsd() возвращает false при неудаче, поэтому всегда проверяйте результат перед итерацией — вызов foreach на false выдаст предупреждение и ничего не обработает.
<?php
$entries = ftp_mlsd($ftp, '/path/that/may/not/exist');
if ($entries === false) {
echo "Failed to retrieve the directory listing.\n";
} else {
foreach ($entries as $entry) {
echo $entry['name'] . "\n";
}
}Используйте строгое сравнение === false. Пустая директория возвращает пустой array [], который является ложным значением — нестрогая проверка if (!$entries) ошибочно расценила бы пустую (но корректную) директорию как ошибку.
Распространённые причины сбоя ftp_mlsd():
- Сервер не поддерживает команду
MLSD(устаревшие или минималистичные FTP-серверы). Используйтеftp_rawlist()в качестве запасного варианта. - Путь к директории указан неверно, или у вас нет прав на её чтение.
- Вы ещё не вошли в систему, или соединение истекло по таймауту.
ftp_mlsd() в сравнении с другими функциями листинга
| Функция | Возвращает | Лучше всего подходит для |
|---|---|---|
ftp_mlsd() | Структурированный array (name, type, size, modify…) | Надёжные метаданные на разных серверах (PHP 7.2+) |
ftp_nlist() | Плоский array имён | Быстрый список только имён файлов |
ftp_rawlist() | Array необработанных строк в стиле ls | Устаревшие серверы без поддержки MLSD |
Заключение
ftp_mlsd() — современный и надёжный способ получить листинг FTP-директории в PHP: она возвращает структурированный array с типом, размером и временем изменения каждой записи, избавляя вас от хрупкого разбора текста, которого требуют старые функции. Используйте её совместно с ftp_connect(), ftp_login() и ftp_close() для полноценного и надёжного рабочего процесса листинга FTP — и не забывайте проверять === false перед итерацией.