belca/filehandler

File handler for Dios CMS

v0.4 2019-05-28 12:38 UTC

This package is auto-updated.

Last update: 2025-02-23 18:38:55 UTC


README

FileHandler - расширяемый пакет для обработки файлов: получения информации о файле, изменения оригинального файла, создания модификаций файлов и т.п.

Изначально FileHandler разработан для Dios CMS в качестве единого интерфейса для обработки загружаемых и уже сохраненных файлов. Пакет может использоваться в любом PHP-проекте.

Что может FileHandler?

Пакет не содержит функций обработки и сам не обрабатывает файлы.

По умолчанию пакет предоставляет возможности для удобной обработки файлов: единые интерфейсы, адаптеры обработчиков и базовую реализацию классов.

Все обработчики файлов необходимо разрабатывать самостоятельно или использовать сторонние обработчики, в т.ч. из Dios CMS, если они подходят для ваших задач.

При этом, функции FileHandler позволяют:

  1. задать правила и сценарии обработки файлов (конфигурацию обработки файлов);
  2. задать список локальных и/или глобальных обработчиков;
  3. задать исходный файл (оригинальный файл) для обработки;
  4. обработать оригинальный файл модифицируя его и/или извлекая свойства файла;
  5. создать модификации оригинального файла и получить свойства модификаций.

Определения и особенности работы пакета

В основе реализации пакета используется два интерфейса:

  • FileHandler - точка входа для обработки файлов;
  • FileHandlerAdapter - адаптер обработки файлов вызывающиеся из FileHandler и реализующий связь между FileHandler и сторонним пакетом (библиотекой, классом) для обработки файлов.

FileHandlerAdapter

Адаптер используется для связи функций между экземпляром FileHandler, который вызывает обработчиков, и классом-обработчиком (например, FInfo или FGen).

Основные функции интерфейса FileHandlerAdapter уже реализованы в абстрактном классе FileHandlerAdapterAbstract. При необходимости вы можете использовать свой класс или реализовать несколько оставшихся методов: construct, merge, getHandlerType и handle.

Задачи construct

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

Если ваш обработчик работает только со статическими методами и его не надо инициализировать, то при необходимости вы можете задать в конструкторе конфигурацию.

Задачи метода merge

Данный метод используется для слияния нескольких конфигураций. Например, конфигурация по умолчанию, и конфигурация пользователя, заданная на странице веб-приложения.

Метод принимает способ (метод) слияния конфигурации и неограниченное количество наборов конфигурации. Вся передаваемая конфигурация должна иметь один формат.

Задачи метода handle

Запускает обработку файла по указанному сценарию, если он используется (не каждому обработчику нужен сценарий обработки), и сохраняет полученные значения для возвращения через метод getInfo.

Задачи метода getHandlerType

Метод возвращает тип обработчика файла. Данный метод может возвращать константу без переменной или же обращаться к приватной переменной и возвращать ее значение.

Лучше возвращать константу без переменной, т.к. тип обработчика не должен изменяться во время работы.

Типы обработчиков файла

Адаптер может возвращать один из трех типов обработчиков:

  1. extracting - извлекающий тип обработчика;
  2. generating - генерирующий тип обработчика;
  3. modifying - модифицирующий тип обработчика.

Извлекающий обработчик обрабатывает один файл и не создает новые файлы (не модифицирует оригинальный файл и не создает модификации оригинального файла). Извлекающий обработчик только возвращает сведения о файле.

Типичным примером реализации извлекающего обработчика служит реализация адаптера обработчика на основе пакета FInfo.

В некоторых случаях извлечение свойств может требовать создание временных файлов для получения свойств. Если временные файлы в последующем не будут использованы (автоматически будут заменены другими данными или удалены), то такой обработчик по прежнему считается извлекающим. Если временный файл будет использован для регулярного использования, то он уже не временный, и соответственной такой обработчик не может быть извлекающим.

Модифицирующий обработчик изменяет оригинальный файл и возвращает новые сведения о файле (формат, тип, размер и т.п.). Это может быть сделано как реализующим классом обработчика, так и другими обработчиками, если это надо.

При изменении пути к оригинальному файлу (после создания нового исходного файла с новым именем) должен быть возвращен новый путь к файлу. Он будет использован для дальнейшей обработки файла.

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

Примером модифицирующего обработчика может послужить изменение размера загружаемого изображения. Например, на сервер было загружено фото с размерами 3543x5315 px. Размер такого файла на носителе будет занимать несколько Мб (3-15 МБ). При загрузке 100 подобных фотографий будет занято от 300 до 1500 Мб, а в некоторых случаях это может быть очень много. На разработанном веб-сайте или в веб-приложении для отображения используются модификации фото с размерами не превышающие 600px в ширину. Соответственно, если нам никогда не понадобятся оригинальные размеры исходных фото, то все фото могут быть сжаты хотя бы до 1000px в ширину (или меньше) и дополнительно может быть применено снижение качества изображения. В результате на выходе мы получим размер одной фотографии на носителе не превышающий 250 Кб (100-250 Кб). Т.о. общий размер "исходных" модифицированных фотографий может занимать в хранилище 10-25 Мб. Это значительно меньше 300-1500 Мб, а значит можно хранить на сервере намного больше фото.

Бывают случаи, когда все-таки нужно сохранять оригинальный файл в таком виде, котором он был загружен или хотя бы с минимальными изменениями. Оригинальный файл может быть использован при массовой повторной генерации всех существующих файлов. Например, компания поменяла логотип организации или название, а все изображения и файлы имели защитные знаки с предыдущим логотипом и названиями. Необходимо на все существующие файлы нанести новые данные, а предыдущие версии файлов удалить.

Генерирующий обработчик создает новые файлы на основе оригинального файла. В дополнение к новым файлам могут быть получены дополнительные сведения о файле, которые возвращаются непосредственно из самого адаптера-обработчика.

Типичные сведения возвращаемые генерирующим обработчиком:

  • путь к новым файлам (модификациям);
  • краткие сведения о файле (тип, размер).

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

Типичным примером модификации файлов может быть загрузка аватара профиля или изображений для статей блога на сервер. Для снижения нагрузки на канал передачи данных и увеличение скорости загрузки страниц будут использованы не оригинальные файлы, которые могут превышать 1 Мб, а их модификации - миниатюры или уменьшенные изображения с размером от 20 до 100 Кб. Это позволяет снизить нагрузку на передачу данных, например при использовании большого количества изображений (список пользователей, галереи изображений).

В отличии от модифицирующих обработчиков, которые в первую очередь нацелены на замену оригинальных файлов и обычно для уменьшения занимаемого пространства или создания единообразного хранилища файлов (приводить все загружаемые документы к формату PDF), генерирующий обработчик увеличивает занимаемое место на сервере, создавая к одному оригинальному файлу 3-10 модификаций файлов для создания комфортной работы пользователей.

Как показывает практика разработки веб-сайтов, комбинирование модифицирующего и генерирующего обработчиков приводит к компромиссу. В результате вместо одного изображения с размером 3-5 Мб на сервере будет использован измененный оригинальный файл с размером до 500 Кб и будет создано 5-8 модификаций суммарно не превышающие 1.5 Мб. В результате на сервере будет занято всего лишь около 2 Мб, вместо 3-5 Мб.

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

FileHandler

Данный интерфейс и его реализация используется для задания конфигураций обработки, вызова всех обработчиков и получения данных после обработки.

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

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

Обработка оригинального файла и создание модификаций файлов задается отдельно, при условии, что будут соблюдены правила формирования конфигурации обработки файлов (обработчики оригинального файла не должны создавать модификации, а генерирующие обработчики не должны изменять и заменять оригинальный файл).

FileHandler позволяет извлекать конкретные (базовые) свойства результата обработчиков файла и дополнительные.

В таблице перечислены основные методы класса. Более подробная информация содержится в самих классах.

Метод класса Описание
setOriginalFile($file, $fileinfo = []) Задает файл для обработки. Вторым параметром может быть передана информация о файле (ассоциативный массив): оригинальное имя, тип файла, расширение файла. Оригинальным файлом может быть загруженный файл методом POST, находящийся во временной директории PHP (например, /tmp/filename).
setDirectory($directory = '') Устанавливает рабочую директорию для сохранения новых файлов или сохранения оригинального файла.
setHandlers($handlers = [], $method = self::METHOD_MERGE) Задает список обработчиков файла и метод слияния данных. Все обработчики должны реализовывать интерфейс FileHandlerAdapter.
save($filename = null, $replace = true) Сохраняет оригинальный файл в указанную директорию или если задано новое имя файла с относительным путем к файлу от рабочей директории, то туда. Если файл существует, то он будет заменен, если не изменен второй параметр на false.
handle($params = null) Запускает обработку файла.
getFilePath() Возвращает путь к новому (сохраненному или модифицированному) исходному файлу.
getFilePaths() Возвращает пути к файлам-модификациям, если они были созданы.
getFileInfo($handlerGroups = true) Возвращает сгруппированную информацию об оригинальном файле.
getAllInfo($handlerGroups = true) Возвращает сгруппированную информацию о всех файлах-модификациях, если они существуют.
setBasicPropertyNames($properties) Устанавливает названия основных свойств файла. Название свойств указываются через точку (например, 'finfo.color'), где первое значение - имя обработчика, второе - имя возвращаемого свойства обработчиком.
getBasicFileProperties($handlerGroups = false) Возвращает основную информацию о файле в соответствии с основными полями. По умолчанию результат не объединяется в группы обработчиков, т.к. чаще всего эти значения используются для массовой записи в основные поля таблицы. При необходимости этот параметр можно изменить.
getAdditionalFileProperties($handlerGroups = true) Возвращает дополнительную информацию о файле в соответствии с основными полями (возвращает все свойства, кроме заданных).
getBasicProperties($handlerGroups = false) Возвращает базовые свойства всех файлов-модификаций. Такой же принцип как у оригинального файла.
getAdditionalProperties($handlerGroups = true) Возвращает дополнительные свойства всех файлов в соответствии с основными полями (возвращает все свойства, кроме заданных).

Как использовать FileHandler?

Установите FileHandler через composer (хранилище Packagist) или сделав клон с репозитория Github.

$handlers = [ 'finfo' => \Belca\File\FileHandler\FInfoHandler::class, ];

$rules = [ 'finfo' => [ 'handlers' => [ 'basic' => \Belca\FInfo\BasicFileinfo::class, ] ], ];

$scripts = [ 'user-device' => [ 'sequence' => ['fgen', 'finfo'], 'properties' => ['finfo.size', 'finfo.mime' => 'mimetype', 'finfo.created'], 'handlers' => [ 'fgen' => [], 'finfo' => [], ], ], ];

$directory = '/usr/www/html/webapp/files';

$fileHandler = new FileHandler($handlers, $rules, $scripts); // Правила обработки и скрипты могут быть изменены отдельно $fileHandler->setDirectory($directory); $fileHandler->setOriginalFile($originalFile, $fileinfo); $fileHandler->setNameExecutableScript($scriptName);

// Последовательность выполнения обработчиков может быть задана в сценарии обработки файла $fileHandler->setHandlersSequence($sequence);

// Базовые свойства могут быть заданы в сценарии обработки файла $fileHandler->setBasicPropertyNames($basicPropertyNames);

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

// При необходимости можно объединить правила обработки или сценарии обработки // после инициализации класса. Также можно воспользоваться утилитами для // объединения данных за пределами экземпляра класса. FilaHandlerUtility

// Сохраним оригинальный файл в новую директорию и выполним обработку if ($fileHandler->save($filename)) { $fileHandler->handle($script);

// Получаем информацию после обработки файла

// Информация об оригинальном файле
$basicFileinfo = $fileHandler->getBasicFileProperties();
$additionalFileinfo = fileHandler->getAdditionalFileProperties();

// Информация о модификациях
$basicPropertiesModifications = $fileHandler->getBasicProperties();
$additinalPropertiesModifications = $fileHandler->getAdditionalProperties();

}

Разработка и подключение обработчиков (FileHandlerAdapter)

Другие особенности FileHandler

Лицензия

Пакет распространяется с лицензией MIT.