Вступление

Laravel обеспечивает мощную абстракцию файловой системы благодаря замечательному PHP-пакету Flysystem Фрэнка де Йонга. Интеграция Laravel Flysystem предоставляет простые в использовании драйверы для работы с локальными файловыми системами, Amazon S3 и Rackspace Cloud Storage. Более того, удивительно просто переключаться между этими вариантами хранения, поскольку API остается одинаковым для каждой системы.

 

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

Файл конфигурации файловой системы находится по адресу . В этом файле вы можете настроить все ваши «диски». Каждый диск представляет определенный драйвер хранилища и место хранения. Примеры конфигурации для каждого поддерживаемого драйвера включены в файл конфигурации. Поэтому измените конфигурацию в соответствии с вашими предпочтениями и учетными данными.config/filesystems.php

Вы можете настроить столько дисков, сколько хотите, и даже иметь несколько дисков, которые используют один и тот же драйвер.

 

Публичный диск

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

Чтобы создать символическую ссылку, вы можете использовать команду Artisan:storage:link

php artisan storage:link

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

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

 

Местный водитель

При использовании localдрайвера все файловые операции относятся к rootкаталогу, определенному в вашем файле конфигурации. По умолчанию это значение установлено в каталог. Поэтому следующий метод будет хранить файл в :storage/appstorage/app/file.txt

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

 

Необходимые условия для водителя

Композитор Пакеты

Перед использованием драйверов SFTP, S3 или Rackspace вам необходимо установить соответствующий пакет через Composer:

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

Для производительности абсолютно необходимо использовать кэшированный адаптер. Для этого вам понадобится дополнительный пакет:

  • CachedAdapter: league/flysystem-cached-adapter ~1.0

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

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

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

Интеграция Laravel с Flysystem прекрасно работает с FTP; однако пример конфигурации не включен в файл конфигурации фреймворка по умолчанию . Если вам нужно настроить файловую систему FTP, вы можете использовать пример конфигурации ниже:filesystems.php

'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; однако пример конфигурации не включен в файл конфигурации фреймворка по умолчанию . Если вам нужно настроить файловую систему SFTP, вы можете использовать пример конфигурации ниже:filesystems.php

'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,
],

Конфигурация Rackspace Driver

Интеграция Laravel с Flysystem прекрасно работает с Rackspace; однако пример конфигурации не включен в файл конфигурации фреймворка по умолчанию . Если вам нужно настроить файловую систему Rackspace, вы можете использовать пример конфигурации ниже:filesystems.php

'rackspace' => [
    'driver'    => 'rackspace',
    'username'  => 'your-username',
    'key'       => 'your-key',
    'container' => 'your-container',
    'endpoint'  => 'https://identity.api.rackspacecloud.com/v2.0/',
    'region'    => 'IAD',
    'url_type'  => 'publicURL',
],

 

Кэширование

Чтобы включить кэширование для данного диска, вы можете добавить cacheдирективу к параметрам конфигурации диска. Параметр cacheдолжен быть массивом параметров кэширования, содержащих diskимя, expireвремя в секундах и кэш prefix:

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

    // Other Disk Options...

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

 

Получение экземпляров диска

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

use Illuminate\Support\Facades\Storage;

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

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

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

 

Получение файлов

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

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

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

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

 

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

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

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

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

 

URL файлов

Вы можете использовать urlметод, чтобы получить URL для данного файла. Если вы используете localдрайвер, он обычно просто добавляется /storageк указанному пути и возвращает относительный URL-адрес файла. Если вы используете драйвер s3или rackspace, полный URL-адрес удаленного будет возвращен:

use Illuminate\Support\Facades\Storage;

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

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

Временные URL

Для файлов, хранящихся с использованием драйвера s3или rackspace, вы можете создать временный URL-адрес для данного файла, используя temporaryUrlметод. Этот метод принимает путь и DateTimeэкземпляр, указывающий, когда должен истечь URL:

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

Если вам нужно указать дополнительные параметры запроса S3 , вы можете передать массив параметров запроса в качестве третьего аргумента temporaryUrlметоду:

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

Настройка хоста локального URL

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

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

 

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

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

use Illuminate\Support\Facades\Storage;

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

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

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

 

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

Этот putметод может использоваться для хранения необработанного содержимого файла на диске. Вы также можете передать PHP resourceв putметод, который будет использовать базовую потоковую поддержку Flysystem. Использование потоков очень рекомендуется при работе с большими файлами:

use Illuminate\Support\Facades\Storage;

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

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

Автоматическая трансляция

Если вы хотите, чтобы Laravel автоматически управлял потоковой передачей указанного файла в ваше хранилище, вы можете использовать метод putFileили putFileAs. Этот метод принимает либо экземпляр, либо экземпляр и автоматически передает поток в нужное место:Illuminate\Http\FileIlluminate\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 Illuminate\Http\Request;
use App\Http\Controllers\Controller;

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

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

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

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

 

Видимость файла

В интеграции Flysystem от Laravel «видимость» - это абстракция прав доступа к файлам на разных платформах. Файлы могут быть либо объявлены, 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')

 

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

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 Storage;
use League\Flysystem\Filesystem;
use Illuminate\Support\ServiceProvider;
use Spatie\Dropbox\Client as DropboxClient;
use Spatie\FlysystemDropbox\DropboxAdapter;

class DropboxServiceProvider extends ServiceProvider
{
    /**
     * Register bindings in the container.
     *
     * @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переменные. Преобразователь Closure должен возвращать экземпляр . Переменная содержит значения , заданные в течение указанного диска.League\Flysystem\Filesystem$configconfig/filesystems.php

Затем зарегистрируйте поставщика услуг в вашем файле конфигурации:config/app.php

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

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