Статьи

Управление пакетами в Laravel

В этой статье мы продолжим изучение функции управления пакетами в среде 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 .

Как всегда, вы можете оставить свои ценные комментарии и отзывы в ленте ниже!