W3docs

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 перед итерацией.

Практика

Практика
Для чего используется команда FTP MLSD в PHP?
Для чего используется команда FTP MLSD в PHP?
Was this page helpful?