Advertisement
  1. Code
  2. PHP
  3. Laravel

Gestión de paquetes en Laravel

Scroll to top
Read Time: 12 min

() translation by (you can also view the original English article)

En este artículo, exploraremos la función de administración de paquetes en el framework Laravel. En el transcurso del artículo, veremos un ejemplo del mundo real para demostrar el propósito del artículo.

La administración de paquetes en Laravel es una característica importante que le permite agrupar una funcionalidad para que se pueda distribuir fácilmente. Además, siempre puedes publicar tu paquete en repositorios como Packagist y GitHub que permiten que otros desarrolladores se beneficien de tu paquete.

Para demostrar el concepto, construiremos una página de ejemplo en Laravel que cargue una imagen en la nube de Amazon S3. En lugar de ir con el flujo habitual, lo desarrollaremos como un paquete que se distribuirá y mantendrá fácilmente.

Antes de continuar, supongo que ya estás familiarizado con el framework Laravel, ya que no entraré en los detalles de los conceptos básicos de Laravel.

Además, debes tener una cuenta de AWS válida y las credenciales para acceder a la API de Amazon a fin de seguir el ejemplo de este artículo. Por lo tanto, asegúrate de configurar eso primero.

Con todo a mano, estamos listos para sumergirnos en el desarrollo real.

Configurando los archivos del paquete

Miremos rápidamente la lista de archivos que implementaremos a lo largo de este tutorial.

  • composer.json: Necesitamos agregar el mapeo de clases de nuestro paquete en el archivo existente composer.json en la raíz del paquete.
  • config/app.php: Archivo existente que usaremos para agregar una entrada de nuestro proveedor de servicio personalizado para que podamos cargar vistas y rutas usando ese archivo.
  • composer.json: Archivo composer.json específico del paquete en caso de que desees distribuir el paquete con otros.
  • packages/envato/aws/src/Providers/AwsServiceProvider.php: Archivo de proveedor de servicio Laravel habitual que se utilizará para cargar otros componentes del paquete.
  • packages/envato/aws/src/routes/web.php: Esto carga las rutas personalizadas de nuestro paquete.
  • packages/envato/aws/src/Controllers/AwsController.php: Este es el archivo del controlador que maneja la lógica de la aplicación de nuestro paquete.
  • packages/envato/aws/src/views/upload.blade.php: El archivo de vista que maneja la lógica de renderizado.

No te preocupes si no tiene mucho sentido aún, ya que discutiremos todo en detalle a medida que avancemos en él.

Configurando los Prerrequisitos

Como mencionamos anteriormente, nuestro paquete implementa el caso de uso de la carga de archivos a la nube de Amazon S3. En esta sección, revisaremos los requisitos previos que deben configurarse para ejecutar nuestro paquete con éxito.

Como desarrollador de Laravel, debes estar familiarizado con Flysystem, que proporciona una agradable capa de abstracción para interactuar con el sistema de archivos. Proporciona controladores fáciles de usar para que puedas interactuar fácilmente con él, sin importar el tipo de sistema de archivos con el que se trate, ya sea en el sistema de archivos local o en el sistema en la nube AWS S3.

Para habilitar la compatibilidad del sistema de archivos en la nube de Amazon S3 con Flysystem, debes instalar el paquete correspondiente de adaptadores mediante composer.

Continúa y ejecuta el siguiente comando de composer desde la raíz de tu proyecto para instalar el paquete flysystem-aws-s3-v3....

1
$composer require league/flysystem-aws-s3-v3

Tras la ejecución exitosa de ese comando, ahora puedes usar Laravel Flysystem para interactuar con el sistema de archivos en la nube de Amazon S3 de la misma manera que lo hubieras utilizado para el sistema de archivos local.

Ahora, demos un vistazo rápidamente al archivo config/filesystems.php para ver la configuración proporcionada para el sistema de archivos Amazon S3.

1
...
2
...
3
'disks' => [
4
    'local' => [
5
        'driver' => 'local',
6
        'root' => storage_path('app'),
7
    ],
8
9
    'public' => [
10
        'driver' => 'local',
11
        'root' => storage_path('app/public'),
12
        'url' => env('APP_URL').'/storage',
13
        'visibility' => 'public',
14
    ],
15
16
    's3' => [
17
        'driver' => 's3',
18
        'key' => env('AWS_KEY'),
19
        'secret' => env('AWS_SECRET'),
20
        'region' => env('AWS_REGION'),
21
        'bucket' => env('AWS_BUCKET'),
22
    ],
23
],
24
...
25
...

Como puedes ver, la configuración ya está en su lugar para Amazon S3; solamente necesitamos establecer variables de entorno ENV apropiadas en el archivo .env.

Continúa y agrega las siguientes variables en tu archivo .env.

1
AWS_KEY={AWS_KEY_VALUE}
2
AWS_SECRET={AWS_SECRET_VALUE}
3
AWS_REGION={AWS_REGION_VALUE}
4
AWS_BUCKET={AWS_BUCKET_VALUE}
5
AWS_CDN_URL={AWS_CDN_URL_VALUE}

Por supuesto, debes reemplazar los marcadores de posición con tus valores reales. Ahora, estás listo para usar el adaptador Flysystem AWS S3 en tu aplicación Laravel.

Repasando los archivos del paquete

Para crear tu propio paquete Laravel, lo primero es crear una estructura de directorios adecuada que refleje las convenciones del sistema Laravel. Supongo que ya estás ejecutando una aplicación básica de Laravel; de hecho, la aplicación de blog predeterminada también lo hará.

Continúa y crea el directorio de paquetes en la raíz de tu aplicación. Teniendo en cuenta que vas a distribuir tu paquete con otras personas, la estructura preferida de tu paquete debe ser {vendor_name}/{package_name}.

Siguiendo esa convención, continuemos y creemos un directorio envato/aws bajo el directorio de paquetes. Como puedes haber adivinado, envato es el nombre del proveedor, y aws representa el nombre del paquete en sí. Finalmente, crearemos un directorio packages/envato/aws/src que contenga los archivos fuente de nuestro paquete.

Ahora, debemos informar a Laravel sobre nuestro nuevo paquete. Continúa y abre el archivo composer.json en la raíz de tu aplicación Laravel y agrega la entrada "Envato\\Aws\\":"packages/envato/aws/src" en la sección de auto carga como se muestra a continuación.

1
...
2
...
3
"autoload": {
4
    "classmap": [
5
        "database"
6
    ],
7
    "psr-4": {
8
        "App\\": "app/",
9
        "Envato\\Aws\\": "packages/envato/aws/src"
10
    }
11
},
12
...
13
...

Como puedes ver, el espacio de nombres Envato\Aws\ está asignado al directorio packages/envato/aws/src. Ahora, solo necesitamos ejecutar el comando dump-autoload para regenerar las asignaciones del composer.

1
$composer dump-autoload

Ahora puedes usar el espacio de nombres Envato\Aws\ en tu aplicación y recogerá los archivos desde la ubicación correcta.

Archivo Composer del paquete

Ahora, continuemos y agreguemos un archivo composer.json específico del paquete para que puedas distribuir tu paquete al repositorio packagist.

Ve al directorio packages/envato/aws y ejecuta el siguiente comando para generar un archivo composer.json para tu paquete.

1
$composer init

Se te harán las preguntas habituales, de modo que solo haz clic en él y se creará un archivo composer.json.

Por lo menos, debería verse algo como esto.

1
{
2
    "name": "envato/aws",
3
    "description": "Example of File Upload to AWS S3 Cloud",
4
    "minimum-stability": "dev",
5
    "require": {}
6
}

Ruta

En nuestro paquete, crearemos una página simple que muestra el estado del archivo cargado. Por lo tanto, necesitamos crear una ruta asociada con esa página.

Vamos a crear un archivo de ruta en packages/envato/aws/src/routes/web.php.

1
<?php
2
Route::get('aws/s3/upload', 'Envato\Aws\Controllers\AwsController@upload');

¿Requiere alguna explicación? El siguiente paso obvio es crear el archivo del controlador asociado.

Controlador

Vamos a crear un archivo de controlador en packages/envato/aws/src/Controllers/AwsController.php con el siguiente contenido.

1
<?php
2
namespace Envato\Aws\Controllers;
3
4
use App\Http\Controllers\Controller;
5
6
class AwsController extends Controller
7
{
8
  public function upload(\Illuminate\Contracts\Filesystem\Factory $storage)
9
  {
10
    // load s3 storage

11
    $awsS3Storage = $storage->disk('s3');
12
    
13
    // load local storage

14
    $localStorage = $storage->disk('local');
15
16
    // default path of local storage "storage/app"

17
    $sourceFileContents = $localStorage->get('test.jpg');
18
    
19
    // destination filepath in S3 cloud

20
    $destFilePath = 'test_new.jpg';
21
    
22
    // init vars

23
    $imageUrl = '';
24
    $errorMsg = '';
25
26
    // upload file to AWS S3

27
    if ($awsS3Storage->put($destFilePath, $sourceFileContents, 'public'))
28
    {
29
      $imageUrl = env('AWS_CDN_URL') . env('AWS_BUCKET') . '/' . $destFilePath;
30
    }
31
    else
32
    {
33
      $errorMsg = 'Oops! Something went wrong :(';
34
    }
35
36
    // call view

37
    return view('aws::upload', ['imageUrl' => $imageUrl, 'errorMsg' => $errorMsg]);
38
  }
39
}

Repasemos el archivo para entender para qué sirve cada fragmento de código.

Iniciamos las cosas estableciendo un espacio de nombre de nuestro controlador en el espacio de nombres Envato\Aws\Controllers. Recuerda que agregamos el mapeo de Envato\Aws a packages/envato/aws/src en el archivo raíz de composer.json para que pueda encontrar nuestros archivos de paquete.

A continuación, definimos el método de upload que hace necesario sincronizar los archivos locales con la nube de Amazon S3. Lo importante a tener en cuenta aquí es el primer argumento del método de carga que solicita la dependencia \Illuminate\Contracts\Filesystem\Factory. Durante la ejecución, se inyectará el contrato apropiado de Laravel.

Ahora, podríamos usar la instancia de fábrica del sistema de archivos para crear instancias de disco según sea necesario. La instancia de disco en Laravel es el controlador que le permite acceder fácilmente a los sistemas de archivos subyacentes, como el disco local, la nube de Amazon S3 y similares.

1
// load s3 storage

2
$awsS3Storage = $storage->disk('s3');
3
    
4
// load local storage

5
$localStorage = $storage->disk('local');

Para simplificar, transferiremos el archivo de imagen estática que ya está disponible en el almacenamiento local predeterminado de Laravel, y la ruta es storage/app/test.jpg.

Como primer paso, tomemos el contenido del archivo fuente.

1
// default path of local storage "storage/app"

2
$sourceFileContents = $localStorage->get('test.jpg');

Con todo configurado como se mencionó, deberías poder sincronizar un archivo a Amazon S3 utilizando el método put.

1
// upload file to AWS S3

2
if ($awsS3Storage->put($destFilePath, $sourceFileContents, 'public'))
3
{
4
  $imageUrl = env('AWS_CDN_URL') . env('AWS_BUCKET') . '/' . $destFilePath;
5
}
6
else
7
{
8
  $errorMsg = 'Oops! Something went wrong :(';
9
}

Asegúrate de haber configurado correctamente las variables de entorno de AWS, en caso de que algo no funcione como se esperaba.

Y lo último es llamar a un archivo de vista que muestra la imagen sincronizada y un mensaje apropiado.

1
// call view

2
return view('aws::upload', ['imageUrl' => $imageUrl, 'errorMsg' => $errorMsg]);

Por supuesto, aún no hemos creado un archivo de vista, y eso es exactamente de lo que se trata la siguiente sección.

Vista

Vamos a crear un archivo de vista en packages/envato/aws/src/views/upload.blade.php con los siguientes contenidos.

1
<!DOCTYPE html>
2
<html lang="{{ config('app.locale') }}">
3
    <head>
4
        <meta charset="utf-8">
5
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
        <meta name="viewport" content="width=device-width, initial-scale=1">
7
8
        <title>Laravel</title>
9
10
        <!-- Fonts -->
11
        <link href="https://fonts.googleapis.com/css?family=Raleway:100,600" rel="stylesheet" type="text/css">
12
13
        <!-- Styles -->
14
        <style>
15
            html, body {
16
                background-color: #fff;
17
                color: #636b6f;
18
                font-family: 'Raleway', sans-serif;
19
                font-weight: 100;
20
                height: 100vh;
21
                margin: 0;
22
            }
23
24
            .full-height {
25
                height: 100vh;
26
            }
27
28
            .flex-center {
29
                align-items: center;
30
                display: flex;
31
                justify-content: center;
32
            }
33
34
            .position-ref {
35
                position: relative;
36
            }
37
38
            .top-right {
39
                position: absolute;
40
                right: 10px;
41
                top: 18px;
42
            }
43
44
            .content {
45
                text-align: center;
46
            }
47
48
            .title {
49
                font-size: 84px;
50
            }
51
52
            .links > a {
53
                color: #636b6f;
54
                padding: 0 25px;
55
                font-size: 12px;
56
                font-weight: 600;
57
                letter-spacing: .1rem;
58
                text-decoration: none;
59
                text-transform: uppercase;
60
            }
61
62
            .m-b-md {
63
                margin-bottom: 30px;
64
            }
65
        </style>
66
    </head>
67
    <body>
68
        <div class="flex-center position-ref full-height">
69
            @if (Route::has('login'))
70
                <div class="top-right links">
71
                    @if (Auth::check())
72
                        <a href="{{ url('/home') }}">Home</a>
73
                    @else
74
                        <a href="{{ url('/login') }}">Login</a>
75
                        <a href="{{ url('/register') }}">Register</a>
76
                    @endif
77
                </div>
78
            @endif
79
80
            <div class="content">
81
                <div class="title m-b-md">
82
                    File upload to S3 Cloud
83
                </div>
84
85
                <div>
86
                  @if ($imageUrl)
87
                      <img src="{{ $imageUrl }}" width="100"/>
88
                  @else
89
                      <span class="error">{{ $errorMsg }}</span>
90
                  @endif
91
                </div>
92
            </div>
93
        </div>
94
    </body>
95
</html>

Es un archivo de vista bastante estándar que muestra la imagen cargada después de la carga exitosa, o de lo contrario un mensaje de error apropiado.

Proveedor de servicio

Ya casi hemos terminado con nuestro paquete, ya que hemos creado los archivos necesarios. El siguiente paso es crear un proveedor de servicios para que podamos registrar las rutas y vistas de nuestro paquete.

Vamos a crear un archivo de proveedor de servicio en packages/envato/aws/src/Providers/AwsServiceProvider.php con el siguiente contenido.

1
<?php
2
3
namespace Envato\Aws\Providers;
4
5
use Illuminate\Support\ServiceProvider;
6
7
class AwsServiceProvider extends ServiceProvider
8
{
9
  /**

10
   * Bootstrap the application services.

11
   *

12
   * @return void

13
   */
14
  public function boot()
15
  {
16
      // load routes

17
      $this->loadRoutesFrom(__DIR__.'/../routes/web.php');
18
19
      // load view files

20
      $this->loadViewsFrom(__DIR__.'/../views', 'aws');
21
      
22
      // publish files

23
      $this->publishes([
24
      __DIR__.'/../views' => resource_path('views/vendor/aws'),
25
    ]);
26
  }
27
28
  /**

29
   * Register the application services.

30
   *

31
   * @return void

32
   */
33
  public function register()
34
  {
35
  }
36
}

Obviamente, también podrías haber creado el archivo del proveedor de servicios utilizando el comando artisan. Pero habría requerido un paso adicional para mover el archivo de app/Providers a nuestro paquete.

De todos modos, repasemos el archivo del proveedor de servicios que se acabas de crear.

En primer lugar, cargamos las rutas y vistas asociadas a nuestro paquete.

1
// load routes

2
$this->loadRoutesFrom(__DIR__.'/../routes/web.php');
3
4
// load view files

5
$this->loadViewsFrom(__DIR__.'/../views', 'aws');

A continuación, proporcionamos el soporte de publicar las vistas de nuestros paquetes para que los desarrolladores que deseen anular las vistas puedan hacerlo. La próxima vez que ejecuten el comando php artisan vendor:publish, Laravel copie las vistas de packages/envato/aws/src/views/ a resources/views/vendor/aws.

Ahora pueden cambiar las vistas en el directorio resources/views/vendor/aws, y Laravel lo recogerá automáticamente en lugar de las vistas en packages/envato/aws/src/views/. De hecho, es la forma correcta de modificar vistas de paquetes de terceros, en lugar de modificar directamente las vistas de paquetes.

Eso es todo lo que concierne al proveedor del servicio. Como era de esperar, debemos agregar la entrada del proveedor de servicios en config/app.php. Agrega la siguiente entrada en la matriz de providers.

1
...
2
...
3
/*

4
 * Application Service Providers...

5
 */
6
App\Providers\AppServiceProvider::class,
7
App\Providers\AuthServiceProvider::class,
8
App\Providers\BroadcastServiceProvider::class,
9
App\Providers\EventServiceProvider::class,
10
App\Providers\RouteServiceProvider::class,
11
Envato\Aws\Providers\AwsServiceProvider::class, // Our package service provider

12
...
13
...

Y ahí está, todo está en orden ahora, para que podamos seguir adelante y probar nuestro paquete.

Continúa y ejecuta la URL http://tu-aplicación-laravel/aws/s3/upload en tu navegador. Si todo va bien, deberías ver la imagen en tu página cargada desde la nube de Amazon S3. Por favor, avísame si tienes algún problema, estaría encantado de responderte.

Así que... estamos en la nota de cierre de este artículo, ¡y espero que lo hayas disfrutado!

Conclusión

Hoy, hablamos una de las características importantes de la administración de paquetes del framework Laravel. En el proceso de configuración de nuestro paquete Laravel personalizado, revisamos un ejemplo del mundo real que demostró cómo podías cargar una imagen en la nube de Amazon S3.

Es una característica muy agradable si deseas agrupar y distribuir un conjunto de funcionalidades. De hecho, podrías ver esto como una opción para abordar el desarrollo de tu módulo personalizado en Laravel.

Para aquellos de ustedes que recién están comenzando con Laravel o buscando ampliar su conocimiento, sitio o aplicación con extensiones, tenemos una variedad de cosas que pueden estudiar en Envato Market.

Como siempre, puedes dejar tus valiosos comentarios y sugerencias en el feed a continuación.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.