Данная инструкция подробно описывает, как подключить Amazon S3-совместимое облачное хранилище к приложению Laravel. В процессе вы научитесь выполнять настройку подключения, загружать файлы через интерфейс, маршруты и формы, а также оптимизировать изображения перед загрузкой.
Мы используем S3-хранилище от Timeweb Cloud для демонстрации возможностей интеграции. Оно отлично подходит для хранения медиафайлов, резервных копий и других данных благодаря своей масштабируемости, надежности и безопасности. Следуя данной инструкции, вы сможете легко настроить свое приложение для работы с Timeweb Cloud S3 и эффективно управлять хранилищем данных.
Amazon S3 (Simple Storage Service) — это облачное хранилище для безопасного и масштабируемого хранения данных. Подходит для файлов любого размера и формата, часто используется для хранения изображений, видеороликов, резервных копий и других данных.
Преимущества S3:
Если у вас есть сайт с большим количеством медиа-контента, таким как изображения или видео, Amazon S3 станет более выгодным и эффективным решением, чем покупка сервера с большим объемом диска. S3 позволяет гибко масштабировать хранилище под ваши нужды, обеспечивает высокую надежность данных и избавляет от забот о физических серверах. Вы платите только за использованные ресурсы, а встроенные инструменты безопасности и интеграции делают его идеальным выбором для работы с большими объемами данных.
Нажмите кнопку «Заказать».
Для примера будем использовать публичное хранилище с фиксированным размером 10 ГБ.
s3
Создайте HTML-файл:
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Тест изображения</title>
</head>
<body>
<h1>Тест изображения</h1>
<img src="ссылка_на_изображение" alt="Мое первое изображение">
</body>
</html>
Откройте HTML-файл в браузере. Если изображение отображается, загрузка выполнена успешно.
Установите Laravel с помощью Composer:
composer create-project laravel/laravel:^8.0 laravel-s3.loc
Установите библиотеку Flysystem:
composer require league/flysystem-aws-s3-v3 "^1.0"
В файле config/filesystems.php
найдите раздел с ключом s3
и создайте новый, например, tws3
. Это удобно, если планируете использовать несколько облачных хранилищ или хотите отличить настройки Timeweb Cloud от других:
'tws3' => [
'driver' => 's3', // Этот параметр остается неизменным
'key' => env('TW_ACCESS_KEY_ID'), // Указываем переменную окружения для ключа доступа
'secret' => env('TW_SECRET_ACCESS_KEY'), // Указываем переменную окружения для секретного ключа
'region' => env('TW_DEFAULT_REGION'), // Регион Timeweb Cloud
'bucket' => env('TW_BUCKET'), // Имя бакета
'url' => env('TW_URL'), // URL для доступа к бакету
'endpoint' => env('TW_ENDPOINT'), // Кастомный endpoint для Timeweb S3
],
tws3
) помогает понять, что этот диск настроен специально для Timeweb Cloud S3.В корневой файл .env
вашего проекта добавьте переменные окружения:
TW_ACCESS_KEY_ID=ваш_ключ # S3 Access Key
TW_SECRET_ACCESS_KEY=ваш_секрет # S3 Secret Access Key
TW_DEFAULT_REGION=регион_s3 # Регион Timeweb Cloud
TW_BUCKET=имя_бакета # Имя бакета
TW_ENDPOINT=https://s3.timeweb.cloud # URL Timeweb S3
Добавьте значения переменных из настроек бакета.
Должно получиться примерно так:
Безопасность: Хранение конфиденциальной информации (ключей доступа) в .env
защищает их от попадания в публичные репозитории (например, GitHub), так как этот файл обычно добавляют в .gitignore
.
Удобство: Все параметры конфигурации собраны в одном месте, что облегчает их редактирование при переходе на другой провайдер или изменении настроек.
Гибкость: При переносе проекта на другой сервер вам достаточно обновить только файл .env, не меняя исходный код.
Добавьте маршрут в файл routes/web.php
:
use Illuminate\Support\Facades\Storage;
Route::get('/upload', function () {
Storage::disk('tws3')->put('image1.jpg', file_get_contents(public_path('image.jpg')));
return 'Файл загружен!';
});
Скопируйте изображение с названием image.jpg
в папку public.
Запустите встроенный сервер для локальной разработки с помощью команды:
php artisan serve
Теперь ваше приложение будет доступно по адресу http://127.0.0.1:8000
или localhost:8000
. В дальнейшем в инструкции будет использоваться адрес localhost
.
Откройте страницу http://localhost:8000/upload
в браузере. Если отображается строка «Файл загружен!», загрузка выполнена успешно. Загрузку файла можно проверить в интерфейсе Timeweb Cloud.
Добавьте маршрут для отображения формы в файл routes/web.php
:
Route::get('/form', function () {
return view('form');
});
Создайте файл resources/views/form.blade.php
:
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Загрузка файла через форму</title>
</head>
<body>
<form action="/upload-form" method="POST" enctype="multipart/form-data">
@csrf
<input type="file" name="image" required>
<button type="submit">Загрузить</button>
</form>
</body>
</html>
Добавьте маршрут для обработки загрузки изображения:
Route::post('/upload-form', function (Illuminate\Http\Request $request) {
$path = $request->file('image')->store('', 'tws3');
return 'Файл загружен через форму!';
});
Откройте страницу http://localhost:8000/form
в браузере. Выберите файл и нажмите «Загрузить». Если отображается строка «Файл загружен через форму!», загрузка выполнена успешно.
Мы можем уменьшить размеры изображений для экономии места в хранилище.
Установите библиотеку Intervention Image
:
composer require intervention/image:^2
Оптимизируйте изображение перед загрузкой:
Route::post('/upload-form', function (Illuminate\Http\Request $request) {
$image = Image::make($request->file('image'))
->resize(800, 600)
->encode('jpg');
Storage::disk('tws3')->put('optimized-image.jpg', $image);
return 'Файл загружен и оптимизирован через форму!';
});
Для демонстрации добавьте следующий маршрут в routes/web.php
:
use Illuminate\Support\Facades\Storage;
Route::get('/view-file', function () {
$url = Storage::disk('tws3')->url('image1.jpg'); // Укажите имя файла, загруженного в S3
return view('view-file', ['url' => $url]);
});
Создайте файл resources/views/view-file.blade.php
с содержимым:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Отображение файла из S3</title>
</head>
<body>
<h1>Ваш файл из S3</h1>
<img src="{{ $url }}" alt="Файл из S3" style="max-width: 100%; height: auto;">
</body>
</html>
Откройте страницу http://localhost:8000/view-file
в браузере и запустите инспектор кода, нажав клавишу F12. Перейдите на вкладку «Elements» и найдите тег <img>
. В атрибуте src
вы увидите ссылку, указывающую на файл, хранящийся в S3. Это подтверждает успешное отображение изображения из облачного хранилища.
В этом разделе мы рассмотрим, как настроить загрузку и хранение аватаров пользователей в облачном хранилище S3. Аватар будет привязан к пользователю через модель User
, а ссылка на файл будет сохраняться в базе данных SQLite.
apt install php8.3-sqlite3
database/database.sqlite
..env
:DB_CONNECTION=sqlite
DB_DATABASE=/путь/до/проекта/laravel-s3.loc/database/database.sqlite
DB_USERNAME=null
DB_PASSWORD=null
php artisan serve
Для начала создадим новое поле avatar
в таблице users
для хранения ссылки на аватар в облаке.
php artisan make:migration add_avatar_to_users_table --table=users
database/migrations/<временная_метка>_add_avatar_to_users_table.php
следующий код:public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('avatar')->nullable(); // Поле для ссылки на файл аватара в S3
});
}
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('avatar');
});
}
php artisan migrate
Для тестирования создадим пользователя через консоль Tinker — это интерактивная оболочка Laravel, которая позволяет выполнять команды и взаимодействовать с моделями напрямую.
php artisan tinker
User::create(["name"=> "s3","email"=>"s3@email.com","password"=>bcrypt("123456")]);
После выполнения команды вы увидите созданного пользователя. Ему будет присвоен идентификатор 1
, который мы будем использовать в следующих примерах. Если ID отличается, замените его в коде на актуальный.
Добавим три маршрута в файл routes/web.php
для отображения профиля, загрузки аватара и обработки формы.
use App\Models\User;
Route::get('/profile', function () {
$user = User::find(1); // Используем ID ранее созданного пользователя
return view('profile.index', ['user' => $user]);
});
Route::get('/profile/create', function () {
return view('profile.create');
});
use Illuminate\Http\Request;
Route::post('/profile/store', function (Request $request) {
$user = User::find(1); // Используем ID ранее созданного пользователя
$path = $request->file('avatar')->store('avatars', 'tws3'); // Загрузка файла в S3 в папку avatars
$user->avatar = $path; // Сохраняем путь к файлу в базе данных
$user->save();
return redirect('/profile');
});
Для удобства все шаблоны будут храниться в папке resources/views/profile
.
resources/views/profile/create.blade.php
):<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Создание пользователя</title>
</head>
<body>
<form action="/profile/store" method="POST" enctype="multipart/form-data">
@csrf
<label for="avatar">Выберите изображение:</label>
<input type="file" name="avatar" id="avatar" required>
<button type="submit">Загрузить</button>
</form>
</body>
</html>
resources/views/profile/index.blade.php
):<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Профиль пользователя</title>
</head>
<body>
<h1>Профиль пользователя</h1>
<p>{{$user->name}}</p>
<!-- Отображение аватара -->
@if ($user->avatar)
<img src="{{ Storage::disk('tws3')->url($user->avatar) }}"
alt="Аватар"
style="width: 150px; height: 150px; border-radius: 50%;">
@else
<p>Аватар отсутствует.</p>
@endif
</body>
</html>
Теперь у вас настроена загрузка и отображение аватаров пользователей через S3.
/profile/create
и загрузите аватар./profile
, где можно увидеть аватар.<img>
. В атрибуте src
вы увидите ссылку, указывающую на файл, хранящийся в S3.Выгодные тарифы на облако в Timeweb Cloud
Интеграция Laravel с Timeweb Cloud S3 предоставляет гибкие и безопасные возможности для хранения данных. Следуя этой инструкции, вы освоите подключение S3-совместимого хранилища, научитесь загружать файлы через интерфейс, маршруты и формы, а также настраивать отображение файлов, таких как аватары пользователей.
Эти решения помогут вам:
Теперь ваше Laravel-приложение готово к работе с S3-хранилищем, что позволяет сосредоточиться на развитии функциональности и удобстве для пользователей.