Файловая система

Введение

Imhotep реализует собственную файловую систему, которая позволяет максимально комфортно работать с локальной файловой системой и Amazon S3.

Конфигурирование

Настройки файловой системы находятся в файл config/filesystem.php. Здесь можно настроить все "диски" приложения. Диск - это определенный драйвер хранилища и место хранения. В конфигурационном файле включены примеры поддерживаемых дисков и их параметры, который можно легко изменить под требования приложения.

Можно создавать несколько дисков с одинаковым драйвером.

Локальная файловая система

Драйвер local позволяет работать с файлами расположенные относительно корневого каталога приложения. По умолчанию, параметр path задан как storage/app, следовательно, следующий пример запишет файл в storage/app/example.txt:

use Imhotep\Facades\Storage;

Storage::disk('local')->put('example.txt', 'Hello, World!');

Диск public

Диск public, определенный в конфигурационном файле приложения, предназначен для общедоступных файлов. По умолчанию, публичный диск использует драйвер local и хранит файлы в storage/app/public.

Чтобы файлы стали общедоступными, необходимо сделать символическую ссылку на storage/app/public в public/storage. Использование этого соглашения о папках, позволяет хранить публичные файлы в одном каталоге, который может быть легко доступен между развертыванием приложения при использовании системы развертывания с нулевым временем простоя.

Для создания символической ссылки, используйте консольную команду Imhotep storage:link:

php imhotep storage:link

После создания символической ссылке, можно будет создавать URL-адреса для сохраненных файлов, используя помощник asset:

$fileUrl = asset('storage/file.txt');

Imhotep позволяет настроить несколько символических ссылок в конфигурационном файле. Каждая из настроенных ссылок будет создана после запуска консольной команды storage:link:

// Файл: config/filesystem.php

'links' => [
    public_path('storage') => storage_path('app/public'),
    public_path('images') => storage_path('app/images'),
],

Файловые системы, совместимые с Amazon S3

По умолчанию, файл конфигурации содержит диск cloud с драйвером simple_s3. Данный диск можно использовать для взаимодействия с Amazon S3 и другими совместимыми службами хранения файлов, например: MinIO, Yandex Object Storage или DigitalOcean Spaces.

Доступ к экземплярам дисков

Фасад Storage используется для взаимодействия с любым из сконфигурированных дисков. Например, метод put сохранит аватар на диске по умолчанию:

use Imhotep\Facades\Storage;

Storage::put('avatars/1', $content);

Если приложение взаимодействует с несколькими дисками, используйте метод disk фасада Storage для работы с файлами на указанном диске:

Storage::disk('s3')->put('avatars/1', $content);
// или
Storage::disk('public')->put('avatars/1', $content);

Диско по запросу

Иногда может потребоваться создать диск по время выполнения, без настройки его в конфигурационном файле. Для этого используйте метод build фасада Storage:

use Imhotep\Facades\Storage;

$disk = Storage::build([
    'driver' => 'local',
    'root' => '/path/to/root',
]);

$disk->put('image.jpg', $content);

Получение содержания файлов

Метод get используется для получения содержимого файла. Необработанное строковое содержимое файла будет возвращено методом. Помните, что все пути к файлам должны быть указаны относительно параметра «root» диска:

$contents = Storage::get('file.jpg');

Метод exists используется для определения, существует ли файл на диске:

if (Storage::disk('s3')->exists('file.jpg')) {
    // ...
}

Метод missing используется, чтобы определить, отсутствует ли файл на диске:

if (Storage::disk('s3')->missing('file.jpg')) {
    // ...
}

Скачивание файлов

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

return Storage::download('file.jpg');

return Storage::download('file.jpg', $name, $headers);

URL-адреса файлов

Метод url, позволяет получить URL для указанного файла. При использовании драйвера local, к пути файлу добавляется /storage и возвращается относительный URL-адрес файла. При использовании драйвера s3, будет возвращен абсолютный внешний URL-адрес.

use Imhotep\Facades\Storage;

$url = Storage::url('file.jpg');

При использовании драйвера local все файлы, которые должны быть общедоступными, должны быть помещены в каталог storage/app/public. Кроме того, необходимо создать символическую ссылку в public/storage, которая указывает на каталог storage/app/public.

При использовании драйвера local возвращаемое значение url не является URL-кодированным. По этой причине мы рекомендуем всегда хранить ваши файлы, используя имена, которые будут создавать допустимые URL-адреса.

Настройка хоста URL

Если необходимо заранее определить хост для URL-адресов, сгенерированных с помощью фасада Storage, добавьте параметр url в массив конфигурации диска:

'public' => [
    'driver' => 'local',
    'root' => storagePath('app/public'),
    'url' => env('APP_URL').'/storage',
    'visibility' => 'public',
    'throw' => false,
],

Метаданные файла

Метод size возвращает размер файла в байтах:

$size = Storage::size('file.jpg');

Метод lastModified возвращает временную метку UNIX последнего изменения файла:

$time = Storage::lastModified('file.jpg');

Метод mimeType возвращает MIME-тип файла:

$time = Storage::mimeType('file.jpg');

Метод path возвращает путь к указанному файлу. Для драйвера local будет возвращен абсолютный путь к файлу. Для драйвера s3 будет возвращен относительный путь к файлу в корзине S3:

$path = Storage::path('file.jpg');

Хранение файлов

Метод put сохраняет содержимое файла на диске. В качестве содержимого можно передавать resource. Помните, все пути к файлам должны быть указаны относительно «root», настроенного в конфигурации диска:

Storage::put('file.jpg', $contents);

Storage::put('file.jpg', $resource);

Метод возвращает false, если операция завершилась неудачей.

if (! Storage::put('file.jpg', $contents)) {
    // Файл не может быть записан на диск
}

Если в настройках диска параметр throw задан как true, тогда в случае неудачного завершения, будет брошено исключение Imhotep\Contracts\Filesystem\FilesystemException:

'public' => [
    'driver' => 'local',
    // ...
    'throw' => true,
],

Потоковая передача

Методы putFile и putFileAs используют потоковую передачу файлов в хранилище, что позволяет значительно сократить использование памяти. Эти методы принимают экземпляр Imhotep\Support\File или Imhotep\Http\UploadedFile:

use Imhotep\Support\File;
use Imhotep\Facades\Storage;

// Автоматически сгенерировать уникальный идентификатор для имени файла
$path = Storage::putFile('photos', new File('/path/to/photo'));

// Явно указать имя файла
$path = Storage::putFileAs('photos', new File('/path/to/photo'), 'photo.jpg');

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

Добавление информации к файлам

Методы prepend и append позволяют записывать в начало или конец файла, соответственно:

Storage::prepend('file.log', 'Prepended Text');

Storage::append('file.log', 'Appended Text');

Копирование и перемещение файлов

Метод copy копирует существующий файл в новое место, а метод move используется для переименования или перемещения существующего файла в новое место:

Storage::copy('old/file.jpg', 'new/file.jpg');

Storage::move('old/file.jpg', 'new/file.jpg');

Загрузка файлов

Метод store экземпляра Imhotep\Http\UploadedFile сохраняет файл в указанный каталог:

use Imhotep\Http\Request;

Route::post('/uploadAvatar', function (Request $request) {
    $path = $request->file('avatar')->store('avatars');
    // или
    $path = Storage::putFile('avatars', $request->file('avatar'));
});

Указание имени файла

Если необходимо задать конкретное имя файл, используйте метод storeAs:

$path = $request->file('avatar')->storeAs('avatars', $request->user()->id);
// Или
$path = Storage::putFileAs('avatars', $request->file('avatar'), $request->user()->id);

Указание диска

По умолчанию метод store загружаемого файла будет использовать диск по умолчанию. Если необходимо указать другой диск, передайте имя диска в качестве второго аргумента:

$path = $request->file('avatar')->store(
    'avatars/'.$request->user()->id, 's3'
);

Если используется метод storeAs, передать имя диска можно третьим аргументом:

$path = $request->file('avatar')->storeAs(
    'avatars',
    $request->user()->id,
    's3'
);

Дополнительная информация о загружаемом файле

Если нужно получить оригинальное имя или расширение загружаемого файла, вы можете сделать это с помощью методов originalName, originalExtension и originalMimeType:

$file = $request->file('avatar');

$name = $file->originalName();
$extension = $file->originalExtension();
$mimeType = $file->originalMimeType();

Однако имейте в виду, что методы originalName и originalExtension считаются небезопасными, так как имя и расширение файла могут быть изменены злоумышленником. По этой причине лучше использовать методы hashName и extension:

$file = $request->file('avatar');

$name = $file->hashName(); // Генерирует уникальное имя файла
$extension = $file->extension(); // Определяет расширение файла по его MIME-типу

Удаление файлов

Метод delete принимает имя одного файла или массив имен файлов для удаления:

Storage::delete('file.jpg');

Storage::delete('file.jpg', 'file2.jpg');

Storage::delete(['file.jpg', 'file2.jpg']);

При необходимости можно указать диск, с которого следует удалить файл:

Storage::disk('s3')->delete('path/file.jpg');

Каталоги

Получение всех файлов каталога

Метод files возвращает массив всех файлов указанного каталога. Если необходимо получить список всех файлов каталога, включая все подкаталоги, используйте метод allFiles:

$files = Storage::files($directory);

$files = Storage::allFiles($directory);

Получение всех каталогов из каталога

Метод directories возвращает массив всех каталогов указанного каталога. Кроме того, можно использовать метод allDirectories, чтобы получить список всех каталогов внутри указанного каталога и всех их подкаталогов:

$directories = Storage::directories($directory);

$directories = Storage::allDirectories($directory);

Создание каталога

Метод makeDirectory создает указанный каталог, включая подкаталоги:

Storage::makeDirectory('path/to/dir');

Удаление каталога

Для удаления каталога и всех его файлов используйте метод deleteDirectory:

Storage::deleteDirectory('path/to/dir');