Версія фреймворка: 8.x

Зберігання файлів

Вступ

Laravel забезпечує потужну абстракцію файлової системи завдяки чудовомуFlysystemПакет PHP Франка де Йонге. Інтеграція Laravel Flysystem забезпечує прості у використанні драйвери для роботи з локальними файловими системами та Amazon S3. Навіть краще, надзвичайно просто перемикатися між цими параметрами зберігання, оскільки API залишається незмінним для кожної системи.

Конфігурація

Файл конфігурації файлової системи знаходиться за адресоюconfig/filesystems.php. У цьому файлі ви можете налаштувати всі свої "диски". Кожен диск представляє певний драйвер зберігання та місце зберігання. Приклади конфігурацій для кожного підтримуваного драйвера містяться у файлі конфігурації. Отже, змініть конфігурацію, щоб відображати ваші уподобання та облікові дані.

Ви можете налаштувати скільки завгодно дисків і навіть мати кілька дисків, що використовують один і той же драйвер.

Public диск

publicдиск призначений для файлів, які будуть загальнодоступними. За замовчуваннямpublicдиск використовуєlocalдрайвер і зберігає ці файли вstorage/app/public. Щоб зробити їх доступними з Інтернету, вам слід створити символічне посилання зpublic/storageдоstorage/app/public. Ця угода зберігатиме ваші загальнодоступні файли в одному каталозі, до яких можна легко ділитися між розгортаннями при використанні нульових систем розгортання, таких якНадіслати.

Для створення символічного посилання ви можете використовуватиstorage:linkКоманда ремісників:

php artisan storage:link

Після збереження файлу та створення символічного посилання ви можете створити URL-адресу файлів за допомогоюassetпомічник:

echo asset('storage/file.txt');

Ви можете налаштувати додаткові символічні посилання у своємуfilesystemsфайл конфігурації. Кожне з налаштованих посилань буде створено під час запускуstorage:linkкоманда:

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

Local Driver

При використанніlocalдрайвера, всі файлові операції відносяться доrootкаталог, визначений у вашомуfilesystemsфайл конфігурації. За замовчуванням це значення має значенняstorage/appкаталог. Отже, наступний метод зберігає файл уstorage/app/file.txt:

Storage::disk('local')->put('file.txt', 'Contents');

Дозволи

publicвидимістьперекладає на0755для каталогів і0644для файлів. Ви можете змінити зіставлення дозволів у вашомуfilesystemsфайл конфігурації:

'local' => [
    'driver' => 'local',
    'root' => storage_path('app'),
    'permissions' => [
        'file' => [
            'public' => 0664,
            'private' => 0600,
        ],
        'dir' => [
            'public' => 0775,
            'private' => 0700,
        ],
    ],
],

Передумови драйвера

Пакети composer

Перш ніж використовувати драйвери SFTP або S3, вам потрібно встановити відповідний пакет через Composer:

  • SFTP:league/flysystem-sftp ~1.0
  • Amazon S3:league/flysystem-aws-s3-v3 ~1.0

Абсолютно необхідним для продуктивності є використання кешованого адаптера. Для цього вам знадобиться додатковий пакет:

  • Кешований адаптер:league/flysystem-cached-adapter ~1.0

Конфігурація драйвера S3

Інформація про конфігурацію драйвера S3 знаходиться у вашомуconfig/filesystems.phpфайл конфігурації. Цей файл містить приклад масиву конфігурації для драйвера S3. Ви можете змінювати цей масив за допомогою власної конфігурації S3 та облікових даних. Для зручності ці змінні середовища відповідають умовам іменування, що використовуються AWS CLI.

Конфігурація драйвера FTP

Інтеграція Laravel Flysystem чудово працює з FTP; однак, зразок конфігурації не входить у стандартну структуру фреймворкуfilesystems.phpфайл конфігурації. Якщо вам потрібно налаштувати файлову систему FTP, ви можете скористатися прикладом конфігурації нижче:

'ftp' => [
    'driver' => 'ftp',
    'host' => 'ftp.example.com',
    'username' => 'your-username',
    'password' => 'your-password',

    // Optional FTP Settings...
    // 'port' => 21,
    // 'root' => '',
    // 'passive' => true,
    // 'ssl' => true,
    // 'timeout' => 30,
],

Конфігурація драйвера SFTP

Інтеграція Laravel Flysystem чудово працює з SFTP; однак, зразок конфігурації не входить у стандартну структуру фреймворкуfilesystems.phpфайл конфігурації. Якщо вам потрібно налаштувати файлову систему SFTP, ви можете скористатися прикладом конфігурації нижче:

'sftp' => [
    'driver' => 'sftp',
    'host' => 'example.com',
    'username' => 'your-username',
    'password' => 'your-password',

    // Settings for SSH key based authentication...
    // 'privateKey' => '/path/to/privateKey',
    // 'password' => 'encryption-password',

    // Optional SFTP Settings...
    // 'port' => 22,
    // 'root' => '',
    // 'timeout' => 30,
],

Кешування

Щоб увімкнути кешування для даного диска, ви можете додати файлcacheдирективу до параметрів конфігурації диска.cacheПараметр повинен бути масивом параметрів кешування, що містить файлdiskім'я,expireчас у секундах та кешprefix:

's3' => [
    'driver' => 's3',

    // Other Disk Options...

    'cache' => [
        'store' => 'memcached',
        'expire' => 600,
        'prefix' => 'cache-prefix',
    ],
],

Отримання екземплярів диска

StorageFacade може використовуватися для взаємодії з будь-яким із налаштованих вами дисків. Наприклад, ви можете використовуватиputметод на фасаді для зберігання аватари на диску за замовчуванням. Якщо ви викликаєте методи наStorageFacadeбез попереднього дзвінка вdiskметод, виклик методу автоматично передається на диск за замовчуванням:

use Illuminate\Support\Facades\Storage;

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

Якщо ваша програма взаємодіє з кількома дисками, ви можете використовуватиdiskметод наStorageFacadeдля роботи з файлами на певному диску:

Storage::disk('s3')->put('avatars/1', $fileContents);

Отримання файлів

getметод може бути використаний для отримання вмісту файлу. Сирий вміст рядка файлу буде повернено методом. Пам'ятайте, що всі шляхи до файлів повинні бути вказані щодо "кореневого" розташування, налаштованого для диска:

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

existsметод може бути використаний для визначення, чи існує файл на диску:

$exists = Storage::disk('s3')->exists('file.jpg');

missingметод може бути використаний для визначення, чи на диску відсутній файл:

$missing = 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 Illuminate\Support\Facades\Storage;

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

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

При використанніlocalдрайвер, повернене значенняurlне кодується URL. З цієї причини ми рекомендуємо завжди зберігати файли, використовуючи імена, які створюватимуть дійсні URL-адреси.

Тимчасові URL-адреси

Для файлів, що зберігаються за допомогоюs3Ви можете створити тимчасову URL-адресу даного файлу за допомогоюtemporaryUrlметод. Цей метод приймає шлях і aDateTimeекземпляр із зазначенням терміну дії URL-адреси:

$url = Storage::temporaryUrl(
    'file.jpg', now()->addMinutes(5)
);

Якщо вам потрібно вказати додатковіПараметри запиту S3, ви можете передати масив параметрів запиту як третій аргумент доtemporaryUrlметод:

$url = Storage::temporaryUrl(
    'file.jpg',
    now()->addMinutes(5),
    [
        'ResponseContentType' => 'application/octet-stream',
        'ResponseContentDisposition' => 'attachment; filename=file2.jpg',
    ]
);

Налаштування хосту URL-адреси

Якщо ви хочете заздалегідь визначити хост для URL-адрес файлів, створених за допомогоюStorageфасад, ви можете додатиurlопція до масиву конфігурації диска:

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

Шляхи до файлів

Ви можете використовуватиpathметод отримати шлях до заданого файлу. Якщо ви використовуєтеlocalдрайвер, це поверне абсолютний шлях до файлу. Якщо ви використовуєтеs3драйвера, цей метод поверне відносний шлях до файлу в сегменті S3:

use Illuminate\Support\Facades\Storage;

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

Файлові метадані

Окрім читання та запису файлів, Laravel може також надавати інформацію про самі файли. Наприклад,sizeметод може бути використаний для отримання розміру файлу в байтах:

use Illuminate\Support\Facades\Storage;

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

lastModifiedМетод повертає мітку часу UNIX останньої зміни файла:

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

Зберігання файлів

putметод може використовуватися для зберігання необробленого вмісту файлу на диску. Ви також можете пройти PHPresourceдоputметод, який використовуватиме базову підтримку потоку Flysystem. Пам'ятайте, що всі шляхи до файлів повинні бути вказані щодо "кореневого" розташування, налаштованого для диска:

use Illuminate\Support\Facades\Storage;

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

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

Автоматичне потокове передавання

Якщо ви хочете, щоб Laravel автоматично керував потоковим передаванням даного файлу до вашого місця зберігання, ви можете використовуватиputFileабоputFileAsметод. Цей метод приймає абоIlluminate\Http\FileабоIlluminate\Http\UploadedFileі автоматично переведе файл у потрібне місце:

use Illuminate\Http\File;
use Illuminate\Support\Facades\Storage;

// Automatically generate a unique ID for file name...
Storage::putFile('photos', new File('/path/to/photo'));

// Manually specify a file name...
Storage::putFileAs('photos', new File('/path/to/photo'), 'photo.jpg');

Є кілька важливих речей, про які слід зазначитиputFileметод. Зауважте, що ми вказали лише ім’я каталогу, а не ім’я файлу. За замовчуваннямputFileметод генерує унікальний ідентифікатор, який служить іменем файлу. Розширення файлу буде визначено шляхом вивчення типу MIME файлу. Шлях до файлу поверне файлputFileметод, щоб ви могли зберігати шлях, включаючи згенероване ім’я файлу, у базі даних.

putFileіputFileAsметоди також приймають аргумент, щоб вказати "видимість" збереженого файлу. Це особливо корисно, якщо ви зберігаєте файл на хмарному диску, такому як S3, і хочете, щоб файл був загальнодоступним:

Storage::putFile('photos', new File('/path/to/photo'), 'public');

Попереднє додавання та додавання до файлів

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');

Завантаження файлів

У веб-додатках одним із найпоширеніших випадків використання файлів є зберігання завантажених користувачами файлів, таких як зображення профілю, фотографії та документи. Laravel дозволяє дуже легко зберігати завантажені файли за допомогоюstoreметод на завантаженому екземплярі файлу. Зателефонуйтеstoreметод із шляхом, за яким ви хочете зберегти завантажений файл:

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class UserAvatarController extends Controller
{
    /**
     * Update the avatar for the user.
     *
     * @param  Request  $request
     * @return Response
     */
    public function update(Request $request)
    {
        $path = $request->file('avatar')->store('avatars');

        return $path;
    }
}

На цьому прикладі слід зазначити кілька важливих речей. Зауважте, що ми вказали лише ім’я каталогу, а не ім’я файлу. За замовчуваннямstoreметод генерує унікальний ідентифікатор, який служить іменем файлу. Розширення файлу буде визначено шляхом вивчення типу MIME файлу. Шлях до файлу поверне файлstoreметод, щоб ви могли зберігати шлях, включаючи згенероване ім’я файлу, у базі даних.

Ви також можете зателефонувати доputFileметод наStorageфасаду, щоб виконати ту ж маніпуляцію файлами, що і в прикладі вище:

$path = Storage::putFile('avatars', $request->file('avatar'));

Вказівка ​​імені файлу

Якщо ви не хочете, щоб ім'я файлу автоматично призначалося вашому збереженому файлу, ви можете використовувати файлstoreAsметод, який отримує в якості аргументів шлях, ім’я файлу та (необов’язковий) диск:

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

Ви також можете використовуватиputFileAsметод наStorageфасад, який буде виконувати таку ж маніпуляцію файлами, як приклад вище:

$path = Storage::putFileAs(
    'avatars', $request->file('avatar'), $request->user()->id
);
Недруковані та недійсні символи Unicode автоматично видаляються із шляхів до файлів. Тому, можливо, ви захочете продезінфікувати шляхи до своїх файлів, перш ніж передавати їх методам зберігання файлів Laravel. Шляхи до файлів нормалізуються за допомогоюLeague\Flysystem\Util::normalizePathметод.

Вказівка ​​диска

За замовчуванням цей метод використовуватиме ваш диск за замовчуванням. Якщо ви хочете вказати інший диск, передайте ім'я диска як другий аргумент у файлstoreметод:

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

Якщо ви використовуєтеstoreAsметоду, ви можете передати ім'я диска як третій аргумент методу:

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

Інша інформація про файл

Якщо ви хочете отримати оригінальну назву завантаженого файлу, ви можете зробити це за допомогоюgetClientOriginalNameметод:

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

extensionметод може бути використаний для отримання розширення файлу завантаженого файлу:

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

Видимість файлу

В інтеграції Laravel Flysystem "видимість" - це абстракція дозволів на файли на декількох платформах. Файли можуть бути оголошеніpublicабоprivate. Коли файл оголошеноpublic, ви вказуєте, що файл, як правило, повинен бути доступним для інших. Наприклад, використовуючи драйвер S3, ви можете отримати URL-адреси дляpublicфайлів.

Ви можете встановити видимість при встановленні файлу черезputметод:

use Illuminate\Support\Facades\Storage;

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

Якщо файл вже зберігався, його видимість можна отримати та встановити за допомогоюgetVisibilityіsetVisibilityметоди:

$visibility = Storage::getVisibility('file.jpg');

Storage::setVisibility('file.jpg', 'public');

Під час взаємодії із завантаженими файлами ви можете використовувати файлstorePubliclyіstorePubliclyAsметоди зберігання завантаженого файлу за допомогоюpublicвидимість:

$path = $request->file('avatar')->storePublicly('avatars', 's3');

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

Видалення файлів

deleteметод приймає одне ім'я файлу або масив файлів для видалення з диска:

use Illuminate\Support\Facades\Storage;

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

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

За необхідності ви можете вказати диск, з якого слід видалити файл:

use Illuminate\Support\Facades\Storage;

Storage::disk('s3')->delete('folder_path/file_name.jpg');

Довідники

Отримати всі файли в каталозі

filesметод повертає масив усіх файлів у даному каталозі. Якщо ви хочете отримати список усіх файлів у даному каталозі, включаючи всі підкаталоги, ви можете використовуватиallFilesметод:

use Illuminate\Support\Facades\Storage;

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

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

Отримати всі каталоги в каталозі

directoriesМетод повертає масив усіх каталогів у даному каталозі. Крім того, ви можете використовуватиallDirectoriesспосіб отримати список усіх каталогів у даному каталозі та всіх його підкаталогів:

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

// Recursive...
$directories = Storage::allDirectories($directory);

Створіть каталог

makeDirectoryметод створить даний каталог, включаючи всі необхідні підкаталоги:

Storage::makeDirectory($directory);

Видалити каталог

Нарешті,deleteDirectoryметод може бути використаний для видалення каталогу та всіх його файлів:

Storage::deleteDirectory($directory);

Спеціальні файлові системи

Інтеграція Laravel Flysystem забезпечує готові драйвери для декількох "драйверів"; однак Flysystem цим не обмежується і має адаптери для багатьох інших систем зберігання. Ви можете створити власний драйвер, якщо хочете використовувати один із цих додаткових адаптерів у своїй програмі Laravel.

Для налаштування власної файлової системи вам знадобиться адаптер Flysystem. Давайте додамо адаптер Dropbox, який підтримується спільнотою, до нашого проекту:

composer require spatie/flysystem-dropbox

Далі слід створити файлпостачальник послугяк отDropboxServiceProvider. У постачальникаbootметод, ви можете використовуватиStorageфасадніextendметод визначення користувацького драйвера:

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Storage;
use Illuminate\Support\ServiceProvider;
use League\Flysystem\Filesystem;
use Spatie\Dropbox\Client as DropboxClient;
use Spatie\FlysystemDropbox\DropboxAdapter;

class DropboxServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Storage::extend('dropbox', function ($app, $config) {
            $client = new DropboxClient(
                $config['authorization_token']
            );

            return new Filesystem(new DropboxAdapter($client));
        });
    }
}

Перший аргументextendметод - це ім'я драйвера, а другий - Закриття, яке отримує$appі$configзмінні. Закриття розв'язувача повинно повернути екземплярLeague\Flysystem\Filesystem.$configзмінна містить значення, визначені вconfig/filesystems.phpдля вказаного диска.

Далі зареєструйте постачальника послуг у своємуconfig/app.phpфайл конфігурації:

'providers' => [
    // ...
    App\Providers\DropboxServiceProvider::class,
];

Після створення та реєстрації постачальника послуг розширення ви можете використовуватиdropboxдрайвер у вашомуconfig/filesystems.phpфайл конфігурації.