В этой статье мы продолжим изучение функции управления пакетами в среде Laravel. В ходе статьи мы рассмотрим пример из реальной жизни, чтобы продемонстрировать цель статьи.
Управление пакетами в Laravel — это важная функция, которая позволяет объединить часть функциональности, чтобы ее можно было легко распространять. Более того, вы всегда можете опубликовать свой пакет в таких репозиториях, как Packagist и GitHub, которые позволят другим разработчикам воспользоваться вашим пакетом.
Чтобы продемонстрировать концепцию, мы создадим пример страницы в Laravel, которая загружает изображение в облако Amazon S3. Вместо того, чтобы идти с обычным потоком, мы разработаем его как пакет, который можно легко распространять и поддерживать.
Прежде чем двигаться дальше, я предполагаю, что вы уже знакомы с фреймворком Laravel, поскольку я не буду вдаваться в детали базовых концепций Laravel.
Кроме того, вам необходимо иметь действительную учетную запись AWS и учетные данные для доступа к API Amazon, чтобы следовать примеру, приведенному в этой статье. Поэтому убедитесь, что вы установили это в первую очередь.
Имея все под рукой, мы готовы погрузиться в реальное развитие.
Настройка файлов пакета
Давайте быстро посмотрим на список файлов, которые мы реализуем на протяжении всего курса.
-
composer.json: нам нужно добавить отображение классов нашего пакета в существующий файлcomposer.jsonв корне пакета. -
config/app.php: это существующий файл, который мы будем использовать для добавления записи нашего провайдера нестандартных услуг, чтобы мы могли загружать представления и маршруты, используя этот файл. -
composer.json: это специфичный для пакета файлcomposer.jsonесли вы хотите распространить пакет среди других. -
packages/envato/aws/src/Providers/AwsServiceProvider.php: обычный файл поставщика услуг Laravel, который будет использоваться для загрузки других компонентов пакета. -
packages/envato/aws/src/routes/web.php: загружает пользовательские маршруты нашего пакета. -
packages/envato/aws/src/Controllers/AwsController.php: это файл контроллера, который обрабатывает логику приложения нашего пакета. -
packages/envato/aws/src/views/upload.blade.php: Файл представления, который обрабатывает логику рендеринга.
Не волнуйтесь, если это пока не имеет особого смысла, так как мы обсудим все подробно, как только мы разберемся с этим.
Настройка предварительных условий
Как мы уже говорили ранее, в нашем пакете реализован вариант загрузки файлов в облако Amazon S3. В этом разделе мы рассмотрим предварительные условия, которые необходимо настроить для успешного запуска нашего пакета.
Как разработчик Laravel, вы должны быть знакомы с Flysystem, которая предоставляет хороший уровень абстракции для взаимодействия с файловой системой. Он предоставляет простые в использовании драйверы, так что вы можете легко взаимодействовать с ним независимо от типа файловой системы, с которой вы имеете дело — будь то локальная файловая система или облачная система AWS S3.
Чтобы включить поддержку облачной файловой системы Amazon S3 с Flysystem, вам необходимо установить соответствующий пакет компоновщика адаптера.
Для установки пакета flysystem-aws-s3-v3 выполните следующую команду composer из корня проекта.
|
1
|
$composer require league/flysystem-aws-s3-v3
|
После успешного выполнения этой команды теперь вы можете использовать Laravel Flysystem для взаимодействия с облачной файловой системой Amazon S3 так же, как вы использовали бы ее для локальной файловой системы.
Теперь давайте быстро config/filesystems.php файл config/filesystems.php чтобы увидеть настройки, предоставляемые для файловой системы Amazon S3.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
…
…
‘disks’ => [
‘local’ => [
‘driver’ => ‘local’,
‘root’ => storage_path(‘app’),
],
‘public’ => [
‘driver’ => ‘local’,
‘root’ => storage_path(‘app/public’),
‘url’ => env(‘APP_URL’).’/storage’,
‘visibility’ => ‘public’,
],
‘s3’ => [
‘driver’ => ‘s3’,
‘key’ => env(‘AWS_KEY’),
‘secret’ => env(‘AWS_SECRET’),
‘region’ => env(‘AWS_REGION’),
‘bucket’ => env(‘AWS_BUCKET’),
],
],
…
…
|
Как видите, конфигурация для Amazon S3 уже установлена; просто нам нужно установить соответствующие переменные ENV в файле .env .
Продолжайте и добавьте следующие переменные в ваш файл .env .
|
1
2
3
4
5
|
AWS_KEY={AWS_KEY_VALUE}
AWS_SECRET={AWS_SECRET_VALUE}
AWS_REGION={AWS_REGION_VALUE}
AWS_BUCKET={AWS_BUCKET_VALUE}
AWS_CDN_URL={AWS_CDN_URL_VALUE}
|
Конечно, вам нужно заменить заполнители их фактическими значениями. Теперь вы готовы использовать адаптер Flysystem AWS S3 в своем приложении Laravel.
Просматривая файлы пакета
Чтобы создать свой собственный пакет Laravel, в первую очередь необходимо создать соответствующую структуру каталогов, которая отражает соглашения системы Laravel. Я предполагаю, что вы уже используете базовое приложение Laravel; на самом деле, приложение блога по умолчанию тоже подойдет.
Идите дальше и создайте каталог packages в корне вашего приложения. Учитывая, что вы собираетесь распространять свой пакет среди других, предпочтительной структурой вашего пакета должна быть {vendor_name}/{package_name} .
Следуя этому соглашению, давайте продолжим и создадим envato/aws каталоге packages . Как вы уже догадались, envato — это имя поставщика, а aws это имя самого пакета. Наконец, давайте создадим packages/envato/aws/src который содержит исходные файлы нашего пакета.
Теперь нам нужно сообщить Laravel о нашем новом пакете. Откройте файл composer.json в корне вашего приложения Laravel и добавьте запись "Envato\\Aws\\": "packages/envato/aws/src" в раздел автозагрузки, как показано ниже.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
|
…
…
«autoload»: {
«classmap»: [
«database»
],
«psr-4»: {
«App\\»: «app/»,
«Envato\\Aws\\»: «packages/envato/aws/src»
}
},
…
…
|
Как видите, пространство имен packages/envato/aws/src Envato\Aws\ сопоставлено с packages/envato/aws/src . Теперь нам просто нужно запустить команду dump-autoload, чтобы восстановить сопоставления композитора.
|
1
|
$composer dump-autoload
|
Теперь вы можете использовать пространство имен Envato\Aws\ в вашем приложении, и оно подберет файлы из правильного места!
Композитор Файл пакета
Теперь давайте продолжим и добавим файл composer.json конкретного пакета, чтобы вы могли распространить свой пакет в хранилище packagist.
Перейдите в packages/envato/aws и выполните следующую команду, чтобы создать файл composer.json для вашего пакета.
|
1
|
$composer init
|
Вам будут предложены обычные вопросы, так что просто просмотрите их, и он создаст файл composer.json .
По крайней мере, это должно выглядеть примерно так.
|
1
2
3
4
5
6
|
{
«name»: «envato/aws»,
«description»: «Example of File Upload to AWS S3 Cloud»,
«minimum-stability»: «dev»,
«require»: {}
}
|
маршрут
В нашем пакете мы создадим простую страницу, которая отображает статус загруженного файла. Поэтому нам нужно создать маршрут, связанный с этой страницей.
Давайте создадим файл маршрута в packages/envato/aws/src/routes/web.php .
|
1
2
|
<?php
Route::get(‘aws/s3/upload’, ‘Envato\Aws\Controllers\AwsController@upload’);
|
Требуется ли вообще какое-либо объяснение? Очевидным следующим шагом является создание соответствующего файла контроллера.
контроллер
Давайте создадим файл контроллера в packages/envato/aws/src/Controllers/AwsController.php со следующим содержимым.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
<?php
namespace Envato\Aws\Controllers;
use App\Http\Controllers\Controller;
class AwsController extends Controller
{
public function upload(\Illuminate\Contracts\Filesystem\Factory $storage)
{
// load s3 storage
$awsS3Storage = $storage->disk(‘s3’);
// load local storage
$localStorage = $storage->disk(‘local’);
// default path of local storage «storage/app»
$sourceFileContents = $localStorage->get(‘test.jpg’);
// destination filepath in S3 cloud
$destFilePath = ‘test_new.jpg’;
// init vars
$imageUrl = »;
$errorMsg = »;
// upload file to AWS S3
if ($awsS3Storage->put($destFilePath, $sourceFileContents, ‘public’))
{
$imageUrl = env(‘AWS_CDN_URL’) .
}
else
{
$errorMsg = ‘Oops!
}
// call view
return view(‘aws::upload’, [‘imageUrl’ => $imageUrl, ‘errorMsg’ => $errorMsg]);
}
}
|
Давайте пройдемся по файлу, чтобы понять, для чего предназначен каждый фрагмент кода.
Мы начинаем, устанавливая пространство имен нашего контроллера в пространство имен Envato\Aws\Controllers . Напомним, что мы добавили отображение Envato\Aws в packages/envato/aws/src в корневом файле composer.json чтобы он мог найти наши файлы пакетов.
Далее мы определили метод upload , который позволяет синхронизировать локальные файлы в облаке Amazon S3. Здесь важно отметить первый аргумент метода загрузки, который запрашивает зависимость \Illuminate\Contracts\Filesystem\Factory . Во время исполнения будет введен соответствующий контракт Laravel.
Теперь мы можем использовать экземпляр фабрики файловой системы для создания экземпляров диска по мере необходимости. Экземпляр диска в Laravel — это драйвер, который позволяет вам легко получать доступ к базовым файловым системам, таким как локальный диск, облако Amazon S3 и тому подобное.
|
1
2
3
4
5
|
// load s3 storage
$awsS3Storage = $storage->disk(‘s3’);
// load local storage
$localStorage = $storage->disk(‘local’);
|
Для простоты мы storage/app/test.jpg файл статического изображения, который уже доступен в локальном хранилище Laravel по умолчанию, и путь к нему — storage/app/test.jpg .
В качестве первого шага, давайте возьмем содержимое исходного файла.
|
1
2
|
// default path of local storage «storage/app»
$sourceFileContents = $localStorage->get(‘test.jpg’);
|
Со всеми настройками, как указано, вы сможете синхронизировать файл с Amazon S3, используя метод put.
|
1
2
3
4
5
6
7
8
9
|
// upload file to AWS S3
if ($awsS3Storage->put($destFilePath, $sourceFileContents, ‘public’))
{
$imageUrl = env(‘AWS_CDN_URL’) .
}
else
{
$errorMsg = ‘Oops!
}
|
Убедитесь, что вы правильно установили переменные среды AWS, на случай, если что-то не сработает, как ожидалось.
И последнее — вызвать файл представления, в котором отображается синхронизированное изображение и соответствующее сообщение.
|
1
2
|
// call view
return view(‘aws::upload’, [‘imageUrl’ => $imageUrl, ‘errorMsg’ => $errorMsg]);
|
Конечно, мы еще не создали файл представления, и это именно то, о чем идет речь в следующем разделе.
Посмотреть
Давайте создадим файл представления в packages/envato/aws/src/views/upload.blade.php со следующим содержимым.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
<!DOCTYPE html>
<html lang=»{{ config(‘app.locale’) }}»>
<head>
<meta charset=»utf-8″>
<meta http-equiv=»X-UA-Compatible» content=»IE=edge»>
<meta name=»viewport» content=»width=device-width, initial-scale=1″>
<title>Laravel</title>
<!— Fonts —>
<link href=»https://fonts.googleapis.com/css?family=Raleway:100,600″ rel=»stylesheet» type=»text/css»>
<!— Styles —>
<style>
html, body {
background-color: #fff;
color: #636b6f;
font-family: ‘Raleway’, sans-serif;
font-weight: 100;
height: 100vh;
margin: 0;
}
.full-height {
height: 100vh;
}
.flex-center {
align-items: center;
display: flex;
justify-content: center;
}
.position-ref {
position: relative;
}
.top-right {
position: absolute;
right: 10px;
top: 18px;
}
.content {
text-align: center;
}
.title {
font-size: 84px;
}
.links > a {
color: #636b6f;
padding: 0 25px;
font-size: 12px;
font-weight: 600;
letter-spacing: .1rem;
text-decoration: none;
text-transform: uppercase;
}
.mb-md {
margin-bottom: 30px;
}
</style>
</head>
<body>
<div class=»flex-center position-ref full-height»>
@if (Route::has(‘login’))
<div class=»top-right links»>
@if (Auth::check())
<a href=»{{ url(‘/home’) }}»>Home</a>
@else
<a href=»{{ url(‘/login’) }}»>Login</a>
<a href=»{{ url(‘/register’) }}»>Register</a>
@endif
</div>
@endif
<div class=»content»>
<div class=»title mb-md»>
File upload to S3 Cloud
</div>
<div>
@if ($imageUrl)
<img src=»{{ $imageUrl }}» width=»100″/>
@else
<span class=»error»>{{ $errorMsg }}
@endif
</div>
</div>
</div>
</body>
</html>
|
Это довольно стандартный файл представления, который отображает загруженное изображение при успешной загрузке или иным образом соответствующее сообщение об ошибке.
Поставщик услуг
Мы почти закончили с нашим пакетом, так как создали необходимые файлы. Следующим шагом является создание поставщика услуг, чтобы мы могли регистрировать маршруты и представления нашего пакета.
Давайте создадим файл поставщика услуг в packages/envato/aws/src/Providers/AwsServiceProvider.php со следующим содержимым.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
<?php
namespace Envato\Aws\Providers;
use Illuminate\Support\ServiceProvider;
class AwsServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
// load routes
$this->loadRoutesFrom(__DIR__.’/../routes/web.php’);
// load view files
$this->loadViewsFrom(__DIR__.’/../views’, ‘aws’);
// publish files
$this->publishes([
__DIR__.’/../views’ => resource_path(‘views/vendor/aws’),
]);
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
}
}
|
Очевидно, вы могли бы создать файл поставщика услуг, используя команду artisan. Но это потребовало бы дополнительного шага перемещения файла из app/Providers в наш пакет.
В любом случае, давайте пройдемся по файлу поставщика услуг, который был только что создан.
Во-первых, мы загружаем маршруты и представления, связанные с нашим пакетом.
|
1
2
3
4
5
|
// load routes
$this->loadRoutesFrom(__DIR__.’/../routes/web.php’);
// load view files
$this->loadViewsFrom(__DIR__.’/../views’, ‘aws’);
|
Затем мы предоставляем поддержку публикации представлений наших пакетов, чтобы разработчики, которые хотят переопределить представления, могли это сделать. В следующий раз, когда они запустят команду php artisan vendor:publish , Laravel packages/envato/aws/src/views/ представления из packages/envato/aws/src/views/ в resources/views/vendor/aws .
Теперь они могут изменять представления в каталоге resources/views/vendor/aws , и Laravel автоматически выберет их вместо представлений в packages/envato/aws/src/views/ . Фактически, это правильный способ изменения сторонних представлений пакетов вместо прямой модификации представлений пакетов.
Вот и все, что касается поставщика услуг. Как и следовало ожидать, нам нужно добавить запись поставщика услуг в config/app.php . Добавьте следующую запись в массиве providers .
|
01
02
03
04
05
06
07
08
09
10
11
12
13
|
…
…
/*
* Application Service Providers…
*/
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
Envato\Aws\Providers\AwsServiceProvider::class, // Our package service provider
…
…
|
И вот вы здесь — все в порядке, так что мы можем пойти дальше и протестировать наш пакет.
Запустите в своем браузере URL http: // your-laravel-application / aws / s3 / upload . Если все идет хорошо, вы должны увидеть изображение на своей странице, загруженное из облака Amazon S3. Пожалуйста, дайте мне знать, если у вас возникнут какие-либо проблемы, и я буду рад ответить на них.
Итак, мы в заключительной ноте этой статьи, и я надеюсь, что вам понравилось!
Вывод
Сегодня мы обсудили одну из важных особенностей инфраструктуры Laravel — управление пакетами. В процессе настройки нашего пользовательского пакета Laravel мы рассмотрели реальный пример, демонстрирующий, как вы можете загрузить изображение в облако Amazon S3.
Это действительно хорошая функция, если вы хотите объединить и распределить набор функций вместе. На самом деле, вы можете рассматривать это как возможность приблизиться к разработке своего пользовательского модуля в Laravel.
Для тех из вас, кто только начинает работать с Laravel или хочет расширить свои знания, сайт или приложение с помощью расширений, у нас есть множество вещей, которые вы можете изучить на Envato Market .
Как всегда, вы можете оставить свои ценные комментарии и отзывы в ленте ниже!