BMC IO DocsBMC IO Docs
IO v6
IO v7
Notes
Docs
IO v6
IO v7
Notes
Docs
  • IO Framework v7

    • О фреймворке
    • Что изменилось в 7 версии
    • IO7 Framework vs Laravel 13 — Сравнение
    • Структура
    • Варианты проектов
    • Доступ к участкам проекта
    • Разворачивание нового проекта
    • Установка проекта
    • Запуск локальной разработки
  • API

    • Обзор API
    • IOCore::call() и IOCore::callAction()
    • Создание API
  • CLI

    • Обзор CLI
    • iocli
    • Кастомные CLI команды
  • Работа с базами данных

    • Обзор работы с базами данных
    • Cron / Планировщик задач (Schedule)
    • Фабрики
    • Миграции
    • Сидеры
    • Query Builder
    • Подключение MinIO
    • Подключение MongoDB
    • Подключение MySQL
    • Подключение PostgreSQL
    • Подключение ProxySQL
    • Подключение RabbitMQ
    • Подключение Redis
  • Логирование

    • Обзор логирования
    • IOEvent - Логирование событий
    • Pinba (PinbaManager) - Профилировщик
  • Модели

    • Обзор моделей
    • CRUD операции
    • Связи моделей
  • Очереди

    • Обзор очередей
    • RabbitMQ
  • Маршруты

    • Обзор маршрутов
    • Определение маршрутов
    • Middleware
  • Сессии

    • Обзор сессий
    • Кроссдоменная SSO
    • JWT авторизация
    • Социальная авторизация
    • OAuth2
    • Keycloak
  • Twig

    • Обзор Twig
    • Формы (FormBuilder)
    • Twig функции
  • Тестирование

    • Обзор тестирования
    • Unit тесты
  • Backend

    • Настройки проекта Conf.php
    • Настройки модуля Module.php
    • Настройки composer
    • Функции фреймворка
    • Вспомогательные функции (Helpers)
    • Глобальные переменные
    • Константы фреймворка
    • Event класс
    • Core класс
    • Route и работа с ними
    • Request и работа с ними
    • Middleware и работа с ними
    • Class и работа с ними
    • Api model и работа с ними
    • Template и работа с ними
    • Мультиязычность и словарь фраз
    • Bin скрипты и работа с ними
    • Cron скрипты и работа с ними
    • $ioSession и работа с сессией
    • $ioHash и работа с кешем
    • $ioXCache и работа с кешем
    • $iodb и работа с базой данных
    • Миграции
  • Frontend

    • Twig шаблонизатор и работа с ним
    • Twig функции
    • Twig фильтры
    • Twig контекст
    • Настройка NPM
    • Сборка Frontend составляющей
    • Обращение к Api через JS
    • Хранилище (store)
    • Навигация в хосте
    • Навигация в микрофронтенде
    • Параметры микрофронтенда
    • Проверка полномочий
  • Tailux UI Компоненты

    • Базовый UI

      • AvatarDot
      • Avatar
      • Badge
      • Button
      • Card
      • ConfirmModal
      • Divider
      • Highlight
      • Tag
    • Загрузка

      • Circlebar
      • Progress
      • Skeleton
      • Spinner
    • Навигация

      • Accordion
      • AccordionButton
      • AccordionHeader
      • AccordionItem
      • AccordionPanel
      • AccordionProvider
      • Pagination
      • PaginationControl
      • PaginationItems
      • PaginationDots
      • PaginationFirst
      • PaginationLast
      • PaginationNext
      • PaginationPrevious
    • Отображение данных

      • Box
      • Collapse
      • ContextualHelp
      • ScrollShadow
      • Timeline
      • TimelineItem
    • Элементы таблиц

      • Table
      • CollapsibleSearch
      • ColumnFilter
      • CopyableCell
      • DateFilter
      • FacetedFilter
      • FilterSelector
      • PaginationSection
      • RadioFilter
      • RangeFilter
      • ResponsiveFilter
      • RoleFilter
      • SelectedRowsActions
      • TableColumnVisibility
      • TableSettings
      • TableSortIcon
    • Элементы форм

      • Checkbox
      • Combobox
      • DatePicker
      • Filepond
      • Input
      • Listbox
      • Radio
      • Range
      • Select
      • StyledSwitch
      • Swap
      • SwapOn
      • SwapOff
      • Switch
      • Textarea
      • TextEditor
      • Upload

Подключение MinIO

Внимание

Данная статья документации написана нейросетью. Возможны некоторые расхождения и неточность информации!

  • Требования
  • MinioManager
    • Инициализация
    • Методы
  • Примеры
    • Базовая загрузка
    • Загрузка из API
    • Генерация ссылки для скачивания
    • Управление файлами
    • Загрузка с ACL
  • Рекомендации
  • FAQ
    • Как настроить MinIO?
    • Как загрузить файл больше 5GB?
    • Как проверить, что файл загружен?
    • Как скачать файл в браузере?
    • Как работает CDN?

Руководство по подключению к MinIO (S3-совместимое хранилище) в IO7 фреймворке.

Требования

Для работы с MinIO необходим пакет aws/aws-sdk-php:

composer require aws/aws-sdk-php

MinioManager

Пространство имён: IO\Storage

Менеджер для работы с MinIO S3-хранилищем. Реализован как синглтон.

Инициализация

init()

public static function init(array $config): self

Инициализировать или получить существующий экземпляр.

ПараметрТипЗначение по умолчаниюОбязателенОписание
$configarray—ДаКонфигурация подключения

Параметры конфигурации:

КлючЗначение по умолчаниюОбязателенОписание
endpoint—ДаURL MinIO сервера
key—ДаAccess Key
secret—ДаSecret Key
bucket—ДаИмя бакета
region'us-east-1'НетРегион
cdn_urlnullНетCDN URL для файлов
use IO\Storage\MinioManager;

MinioManager::init([
    'endpoint' => 'https://minio.example.com',
    'key'      => 'AKIAIOSFODNN7EXAMPLE',
    'secret'   => 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
    'bucket'   => 'my-bucket',
    'region'   => 'us-east-1',
    'cdn_url'  => 'https://cdn.example.com/',
]);

getInstance()

public static function getInstance(): self

Получить синглтон-экземпляр. Выбрасывает \Exception если не инициализирован.

$minio = MinioManager::getInstance();

Методы

upload()

public function upload(
    string $localPath,
    string $remotePath,
    string $acl = 'public-read'
): array

Загрузить файл с локального диска.

ПараметрТипЗначение по умолчаниюОбязателенОписание
$localPathstring—ДаЛокальный путь к файлу
$remotePathstring—ДаУдалённый путь в бакете
$aclstring'public-read'НетACL права

Возвращает:

// Успех:
['success' => true, 'url' => '...', 'cdn_url' => '...']

// Ошибка:
['success' => false, 'error' => '...']
$result = MinioManager::getInstance()->upload(
    '/tmp/photo.jpg',
    'images/2024/photo.jpg'
);

if ($result['success']) {
    echo "Файл загружен: {$result['cdn_url']}";
}

uploadContent()

public function uploadContent(
    string $content,
    string $remotePath,
    string $contentType = 'application/octet-stream'
): array

Загрузить контент напрямую (без файла на диске).

ПараметрТипЗначение по умолчаниюОбязателенОписание
$contentstring—ДаКонтент для загрузки
$remotePathstring—ДаУдалённый путь
$contentTypestring'application/octet-stream'НетMIME тип
$json = json_encode(['config' => 'value']);
$result = MinioManager::getInstance()->uploadContent(
    $json,
    'configs/app.json',
    'application/json'
);

download()

public function download(string $remotePath): array

Скачать файл из бакета.

Возвращает:

// Успех:
['success' => true, 'content' => '...', 'content_type' => '...']

// Ошибка:
['success' => false, 'error' => '...']
$result = MinioManager::getInstance()->download('docs/report.pdf');
if ($result['success']) {
    file_put_contents('/tmp/report.pdf', $result['content']);
}

delete()

public function delete(string $remotePath): array

Удалить файл из бакета.

$result = MinioManager::getInstance()->delete('images/old_photo.jpg');

getTemporaryUrl()

public function getTemporaryUrl(
    string $remotePath,
    int $expires = 3600
): ?string

Получить временную URL для доступа к файлу.

ПараметрТипЗначение по умолчаниюОбязателенОписание
$remotePathstring—ДаПуть к файлу
$expiresint3600НетВремя жизни URL в секундах (1 час)
$url = MinioManager::getInstance()->getTemporaryUrl('docs/private.pdf', 300);
// 'https://minio.example.com/my-bucket/docs/private.pdf?X-Amz-Algorithm=...'

if ($url) {
    header("Location: $url");
}

getMetadata()

public function getMetadata(string $remotePath): array

Получить метаданные файла.

Возвращает:

// Успех:
[
    'success'       => true,
    'size'          => 123456,
    'content_type'  => 'image/jpeg',
    'last_modified' => '2024-01-15 10:30:00',
    'etag'          => '"abc123..."',
]

// Ошибка:
['success' => false, 'error' => '...']
$meta = MinioManager::getInstance()->getMetadata('images/photo.jpg');
echo "Размер: {$meta['size']} байт\n";
echo "Тип: {$meta['content_type']}\n";

listFiles()

public function listFiles(
    string $prefix = '',
    int $maxKeys = 1000
): array

Список файлов в бакете.

ПараметрТипЗначение по умолчаниюОбязателенОписание
$prefixstring''НетПрефикс для фильтрации (все файлы)
$maxKeysint1000НетМаксимальное количество файлов

Возвращает:

// Успех:
[
    'success' => true,
    'files'   => [
        ['key' => 'images/1.jpg', 'size' => 1234, 'last_modified' => '...', 'etag' => '...'],
        // ...
    ],
    'count' => 5,
]

// Ошибка:
['success' => false, 'error' => '...']
$result = MinioManager::getInstance()->listFiles('images/', 50);
foreach ($result['files'] as $file) {
    echo "{$file['key']} ({$file['size']} байт)\n";
}

Примеры

Базовая загрузка

use IO\Storage\MinioManager;

MinioManager::init([
    'endpoint' => 'https://minio.example.com',
    'key'      => 'YOUR_ACCESS_KEY',
    'secret'   => 'YOUR_SECRET_KEY',
    'bucket'   => 'uploads',
]);

// Загрузка фото
$result = MinioManager::getInstance()->upload(
    $_FILES['photo']['tmp_name'],
    'photos/' . time() . '_' . $_FILES['photo']['name']
);

if ($result['success']) {
    echo "Фото загружено: {$result['cdn_url']}";
} else {
    echo "Ошибка: {$result['error']}";
}

Загрузка из API

$content = file_get_contents('php://input');
$result = MinioManager::getInstance()->uploadContent(
    $content,
    'api/data_' . date('Y-m-d') . '.json',
    'application/json'
);

Генерация ссылки для скачивания

// Приватный файл — временная ссылка на 5 минут
$url = MinioManager::getInstance()->getTemporaryUrl(
    'documents/contract.pdf',
    300
);

header("Location: $url");
exit;

Управление файлами

$minio = MinioManager::getInstance();

// Список файлов
$files = $minio->listFiles('uploads/2024/');

// Метаданные
foreach ($files['files'] as $file) {
    $meta = $minio->getMetadata($file['key']);
    echo "{$file['key']}: {$meta['size']} байт, {$meta['content_type']}\n";
}

// Удаление старых файлов
$minio->delete('uploads/2023/old_file.jpg');

Загрузка с ACL

// Приватный файл
$result = MinioManager::getInstance()->upload(
    '/tmp/private.pdf',
    'docs/private.pdf',
    'private'
);

// Публичный файл
$result = MinioManager::getInstance()->upload(
    '/tmp/public.jpg',
    'images/public.jpg',
    'public-read'
);

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

  1. Используйте cdn_url для раздачи статических файлов через CDN
  2. Настройте ACL — private для приватных данных, public-read для публичных
  3. Генерируйте уникальные имена файлов (timestamp + hash)
  4. Используйте getTemporaryUrl() для приватных файлов
  5. Храните структуру — organized by date/type
  6. Проверяйте success перед использованием результата

FAQ

Как настроить MinIO?

# Docker
docker run -p 9000:9000 -p 9001:9001 \
  -e MINIO_ROOT_USER=admin \
  -e MINIO_ROOT_PASSWORD=password \
  minio/minio server /data --console-address ":9001"

Как загрузить файл больше 5GB?

MinIO поддерживает multipart upload через AWS SDK. Используйте uploadContent() для больших файлов или разбейте на части.

Как проверить, что файл загружен?

$meta = $minio->getMetadata($remotePath);
if ($meta['success']) {
    echo "Файл существует, размер: {$meta['size']}\n";
}

Как скачать файл в браузере?

$result = $minio->download('files/report.pdf');
if ($result['success']) {
    header('Content-Type: ' . $result['content_type']);
    header('Content-Disposition: attachment; filename="report.pdf"');
    echo $result['content'];
}

Как работает CDN?

Если задан cdn_url в конфигурации, метод upload() возвращает cdn_url вместо прямой URL MinIO. Используйте cdn_url для раздачи файлов конечным пользователям.

Prev
Query Builder
Next
Подключение MongoDB