Flysystem для PHP: полное руководство с примерами

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Что такое Flysystem и зачем он нужен?

Flysystem — это мощная библиотека для PHP, которая предоставляет единый, унифицированный интерфейс для работы с различными файловыми системами. Разработанная Frank de Jonge, она решает фундаментальную проблему: в реальных проектах код часто жестко привязан к конкретной файловой системе (локальный диск, FTP, Amazon S3, Dropbox и т.д.). Если завтра потребуется перенести хранение файлов с локального сервера на облачное хранилище, придется переписывать значительную часть кода.

Flysystem абстрагирует эту сложность. Вы пишете код один раз, используя единый API, и можете менять "адаптер" (драйвер) файловой системы без изменения бизнес-логики приложения. Это делает ваш код:

  • Гибким — легко переключаться между хранилищами.
  • Тестируемым — можно использовать "фейковую" файловую систему в тестах.
  • Портируемым — код работает одинаково на разных окружениях.

Библиотека используется в таких известных проектах, как Laravel (как основа для диска хранения), Symfony, Drupal и многих других. Flysystem поддерживает десятки адаптеров: Local, FTP/SFTP, Amazon S3, Google Cloud Storage, Azure Blob Storage, WebDAV, Dropbox и даже шифрованные и Zip-архивы.

Установка

Flysystem устанавливается через Composer. Для базовой работы с локальной файловой системой достаточно двух пакетов:

composer require league/flysystem
composer require league/flysystem-local

Важно: Начиная с версии 3.x, Flysystem использует раздельную архитектуру. Основной пакет league/flysystem содержит только интерфейсы и базовые классы. Адаптеры (драйверы) устанавливаются отдельно. Это позволяет подключать только то, что реально нужно.

Для других файловых систем:

  • composer require league/flysystem-ftp — для FTP/SFTP
  • composer require league/flysystem-aws-s3-v3 — для Amazon S3
  • composer require league/flysystem-google-cloud-storage — для Google Cloud
  • composer require league/flysystem-memory — для тестов (виртуальная in-memory ФС)

Быстрый старт

Создадим простой пример: запись, чтение и удаление файла на локальном диске.

<?php
require 'vendor/autoload.php';

use League\Flysystem\Filesystem;
use League\Flysystem\Local\LocalFilesystemAdapter;

// 1. Создаем адаптер для локальной файловой системы
// Указываем корневую директорию, где будут храниться файлы
$adapter = new LocalFilesystemAdapter(__DIR__ . '/storage');

// 2. Создаем экземпляр Filesystem
$filesystem = new Filesystem($adapter);

// 3. Пишем файл
$filesystem->write('hello.txt', 'Привет, мир!');

// 4. Читаем файл
$content = $filesystem->read('hello.txt');
echo $content; // Выведет: Привет, мир!

// 5. Проверяем, существует ли файл
if ($filesystem->fileExists('hello.txt')) {
    echo "Файл существует!";
}

// 6. Удаляем файл
$filesystem->delete('hello.txt');

// 7. Проверяем, что файла больше нет
echo $filesystem->fileExists('hello.txt') ? 'Есть' : 'Нет'; // Выведет: Нет
?>

Обратите внимание: мы не используем file_put_contents(), fopen() или другие нативные PHP-функции. Весь код работает через единый интерфейс Filesystem.

Основные методы/функции

Рассмотрим ключевые методы Flysystem. Все примеры предполагают, что у вас уже создан объект $filesystem.

1. write() — Запись нового файла

Что делает: Создает новый файл или перезаписывает существующий.

Параметры:

  • string $path — путь к файлу
  • string|resource $contents — содержимое файла (строка или ресурс)
  • array $config — опциональные настройки (например, visibility: 'public' или 'private')

Пример:

$filesystem->write('documents/report.txt', 'Ежемесячный отчет за январь');
$filesystem->write('images/logo.png', file_get_contents('local_logo.png'), [
    'visibility' => 'public'
]);

2. read() — Чтение содержимого файла

Что делает: Возвращает содержимое файла в виде строки.

Параметры:

  • string $path — путь к файлу

Пример:

$content = $filesystem->read('documents/report.txt');
echo $content;

3. fileExists() — Проверка существования файла

Что делает: Проверяет, существует ли файл по указанному пути.

Параметры:

  • string $path — путь к файлу

Пример:

if ($filesystem->fileExists('config.json')) {
    echo "Конфигурация найдена";
} else {
    echo "Файл конфигурации отсутствует";
}

4. delete() — Удаление файла

Что делает: Удаляет файл. Если файла не существует, выбрасывает исключение FileNotFoundException.

Параметры:

  • string $path — путь к файлу

Пример:

try {
    $filesystem->delete('temp/cache.dat');
} catch (\League\Flysystem\FileNotFoundException $e) {
    echo "Файл не найден: " . $e->getMessage();
}

5. createDirectory() — Создание директории

Что делает: Создает новую директорию. Автоматически создает все родительские директории, если их нет.

Параметры:

  • string $path — путь к директории
  • array $config — опциональные настройки

Пример:

$filesystem->createDirectory('photos/2024/january');
// Создаст три вложенные директории: photos, 2024, january

6. deleteDirectory() — Удаление директории

Что делает: Удаляет директорию и все её содержимое (рекурсивно).

Параметры:

  • string $path — путь к директории

Пример:

$filesystem->deleteDirectory('temp'); // Удалит temp/ и всё внутри

7. listContents() — Список содержимого директории

Что делает: Возвращает массив объектов FileAttributes или DirectoryAttributes, представляющих содержимое директории.

Параметры:

  • string $path — путь к директории (по умолчанию корень '/')
  • bool $deep — рекурсивно ли просматривать поддиректории (по умолчанию false)

Пример:

$listing = $filesystem->listContents('documents', true);

foreach ($listing as $item) {
    if ($item->isFile()) {
        echo "Файл: " . $item->path() . " (" . $item->fileSize() . " байт)\n";
    } elseif ($item->isDir()) {
        echo "Директория: " . $item->path() . "\n";
    }
}

8. move() — Перемещение/переименование файла

Что делает: Перемещает файл из одного места в другое (или переименовывает).

Параметры:

  • string $source — исходный путь
  • string $destination — целевой путь
  • array $config — опциональные настройки

Пример:

$filesystem->move('incoming/report.csv', 'processed/report_2024.csv');
// Файл будет перемещен и переименован

9. copy() — Копирование файла

Что делает: Копирует файл из одного места в другое. Исходный файл остается нетронутым.

Параметры:

  • string $source — исходный путь
  • string $destination — целевой путь
  • array $config — опциональные настройки

Пример:

$filesystem->copy('templates/email.html', 'backups/email_backup.html');

10. writeStream() / readStream() — Работа с потоками

Что делает: Позволяют работать с файлами как с потоками данных. Критически важно для больших файлов (видео, архивы), чтобы не держать их целиком в оперативной памяти.

Параметры: Аналогичны write() и read(), но вместо строки принимают/возвращают ресурс.

Пример:

// Запись большого файла через поток
$stream = fopen('/tmp/large_video.mp4', 'r');
$filesystem->writeStream('videos/large_video.mp4', $stream);
fclose($stream);

// Чтение большого файла через поток
$stream = $filesystem->readStream('videos/large_video.mp4');
while (!feof($stream)) {
    echo fread($stream, 1024); // Читаем по 1 КБ
}
fclose($stream);

11. setVisibility() — Управление видимостью

Что делает: Устанавливает видимость файла (public или private). Работает не для всех адаптеров (например, для локальной ФС это права доступа Unix).

Параметры:

  • string $path — путь к файлу
  • string $visibility — 'public' или 'private'

Пример:

$filesystem->setVisibility('public/style.css', 'public');
$filesystem->setVisibility('config/db_passwords.php', 'private');

Реальный практический пример: Система загрузки аватаров

Представим, что мы разрабатываем сайт, где пользователи могут загружать свои аватары. Мы хотим хранить их в облаке (S3), но на локальном сервере разработки — на диске. Flysystem позволяет легко переключаться между ними.

<?php
class AvatarService {
    private Filesystem $filesystem;
    private string $avatarPrefix = 'avatars/';

    public function __construct(Filesystem $filesystem) {
        $this->filesystem = $filesystem;
    }

    /**
     * Сохраняет аватар пользователя
     */
    public function uploadAvatar(int $userId, string $sourcePath): string {
        $extension = pathinfo($sourcePath, PATHINFO_EXTENSION);
        $avatarPath = $this->avatarPrefix . $userId .                    

Рекомендаций