Как работать с DigitalOcean Spaces в PHP

В предыдущей статье я тестировал хранилище DigitalOcean, где описал тонкости работы, достоинства и недостатки их сервисов. В этой статье я решил пойти дальше и описать пример работы по API с хранилищем, используя язык программирования PHP.
Если вы ещё не пользовались услугами Digital Ocean, то советую попробовать (уверен, вы не пожалеете). А при регистрации по инструкции из этой статьи, вы получите бонус в размере 100$ на оплату услуг.
- Регистрация ключей доступа Spaces - Manage Keys
- Работа с DigitalOcean Spaces на PHP
- Загрузка приватного файла
- Загрузка публичного файла
Если вы ранее пользовались услугами облачного хранилища, Amazon S3, например, и писали код для работы с ним, то, можете заметить, что раpница между DigitalOcean Spaces и Amazon заключается только в конфигурационных параметрах при аутентификации. В остальном же, их принципы работы одинаковы, в результате чего, они являются полностью взаимозаменяемыми.
А это значит, что вы даже можете использовать готовый Amazon S3 клиент, подключаясь и работая с облачным хранилищем Digital Ocean Spaces. Для разработчиков Laravel вы можете просто использовать существующий драйвер S3 для Flysystem при подключении к DO Spaces.
Создание DigitalOcean spaces access key
Для начала, зарегистрируйтесь в DigitalOcean Spaces по инструкции и сгенерируйте ключ доступа, открыв страницу, и нажав на кнопку управления ключами
Где в секции "Spaces access keys" нужно перейти в меню добавления нового ключа
Теперь осталось лишь как-то его назвать и подтвердить добавление ключа
В итоге, будет создан ключ и секретный код, которые в дальнейшем понадобятся нам для работы с хранилищем по API
Как в PHP работать с DigitalOcean Spaces
Помните, что мы с вами обсуждали, что Digital Ocean Spaces является полностью совместимым и взаимозаменяемым с AWS PHP клиентами. Я продемонстрирую это на практике, и докажу, что это действительно так.
Итак, находим любой Github репозиторий с библиотекой, работающей Amazon AWS, который мы применим под лад работы с Digital Ocean Spaces.
В этом туториале я буду использовать популярную библиотеку для работы с AWS - Flysystem AWS SDK V3
Для начала, подключим эту библиотеку через composer:
composer require league/flysystem-aws-s3-v3
После чего, можем использовать библиотеку под наши нужды, для загрузки файлов в Spaces.
Загрузка приватного файла
Теперь создадим файл do-spaces.php
в корне проекта, и добавим в него такое содержимое:
<?php
require __DIR__ . '/vendor/autoload.php';
use Aws\S3\S3Client;
use League\Flysystem\AwsS3v3\AwsS3Adapter;
use League\Flysystem\Filesystem;
// создание клиента работы с хранилищем
$client = new S3Client([
'credentials' => [
'key' => 'YOUR_key', // ключ с предыдущего шага
'secret' => 'SECRET_KEY' // secret с предыдущего шага
],
'region' => 'fra1', // регион сервера, выбранный во время создания хранилища
'endpoint' => 'https://fra1.digitaloceanspaces.com', // строка, формирующаяся по принципу https://${REGION}.digitaloceanspaces.com
'version' => 'latest',
]);
// вместо YOUR_BUCKET_NAME укажите имя своего хранилища
$adapter = new AwsS3Adapter($client, 'YOUR_BUCKET_NAME');
$filesystem = new Filesystem($adapter);
// загрузка картинки на сервер
$imagePath = __DIR__ . '/example-image.png';
$imageName = basename($imagePath);
$stream = fopen($imagePath, 'r+');
$filesystem->writeStream("images/{$imageName}", $stream, ['visibility' => 'private']);
Посмотреть настройки своего хранилища вы можете на странице Spaces
И последнее, что осталось - добавить в корень проекта файл example-image.png, и проверить работу скрипта, выполнив:
php do-spaces.php
И, если всё было настроено правильно, файл должен был опубликоваться в облачном хранилище.
Но, загрузить приватный файл - то одно дело. А как теперь его прочитать? Для того, чтобы прочитать приватный файл, напишем такой код:
<?php
//...
// создание клиента работы с хранилищем
//$client = new S3Client([...]);
$command = $client->getCommand('GetObject', [
'Bucket' => 'YOUR_BUCKET_NAME', // вместо YOUR_BUCKET_NAME укажите имя своего хранилища
'Key' => 'FILE_PATH' // путь к файлу, в моём случае - images/private2.png
]);
// выполняем команду на получение файла, и задаём срок действия ссылки 10 минут (т.е. через 10 минут ссылка перестанет работать)
$res = $client->createPresignedRequest($command, '+10 minutes');
$signedUrl = (string) $res->getUri();
echo $signedUrl;
В результате выполнения этого кода, мы должны увидеть ссылку, по которой будет доступен наш приватный файл
Загрузка общедоступных (публичных) файлов
Если мы перейдём по URL-адресу ранее загруженной картинки, то получим сообщение об ошибке, вроде этой
Это всё из-за того, что мы загружаем файл как приватный. Однако, в настройках при загрузке (или в панеле DO, для конкретного файла), мы можем указать настройки общего доступа.
Для загрузки общедоступных файлов, модифицируем наш PHP-код:
// заменив строку
$filesystem->writeStream("images/{$imageName}", $stream, ['visibility' => 'private']);
// на новую
$filesystem->writeStream("images/{$imageName}", $stream, ['visibility' => 'public']);
Перед выполнением нового запроса, удалите файл example-image.png с хранилища, который был загружен ранее.
Повторно выполнив скрипт, загрузим файл
php do-spaces.php
Теперь откроем список файлов хранилища, и можем убедиться, что файл загружен, он имеет публичный доступ, и открывается по адресу поддомена, который мы указывали в CDN:
Резюме
В этой статье я показал, как из PHP работать с DigitalOcean облачным хранилищем файлов. Как загружать приватные файлы, и генерировать временные ссылки с подписью для доступа к приватным файлам. А так же, показал, как загружать общедоступные файлы, и открывать их, обращаясь к собственному домену.
Если вам интересно, как устроено API DigitalOcean Spaces внутри, то можете ознакомиться с их документацией по ссылке. И, если будет такое желание, можете реализовать свой собственный клиент для работы с хранилищем.