Tutorial de Laravel para principiantes

ยฟQuรฉ es Laravel?

Laravel es un marco web MVC de cรณdigo abierto para PHP. Laravel es un marco robusto que proporciona un desarrollo sencillo de aplicaciones web PHP con caracterรญsticas como un sistema de empaquetado modular con un administrador de dependencias dedicado, acceso a bases de datos relacionales y otras utilidades para la implementaciรณn y el mantenimiento de aplicaciones.

Laravel fue creado por Taylor Otwell. Desde su lanzamiento inicial en junio de 2011 (versiรณn 1), se ha vuelto cada vez mรกs popular en el sector del framework PHP de la industria del desarrollo web. Gran parte de esta popularidad se puede atribuir a las muchas caracterรญsticas pensadas primero para los desarrolladores que vienen de serie.

ยฟPor quรฉ Laravel?

Alrededor del aรฑo 2000, la mayorรญa Cรณdigos PHP era procesal y podรญa encontrarse en forma de โ€œguionesโ€ que contendrรญan una maraรฑa de cรณdigo espagueti. Incluso las pรกginas mรกs simples no tenรญan separaciรณn de intereses, y por lo tanto era bastante fรกcil que una aplicaciรณn se convirtiera rรกpidamente en una pesadilla de mantenimiento. El mundo necesitaba algo mejor... Ingrese PHP versiรณn 5 y una variedad de marcos PHP que intentan brindar una resoluciรณn muy necesaria y mejores soluciones a diversos problemas de aplicaciones web.

Desde entonces hemos visto muchos frameworks lanzados que allanarรญan el camino para los frameworks populares que existen y se utilizan hoy en dรญa. Hoy, los tres principales serรญan (en nuestra opiniรณn) Zend Framework, Symfony y, por supuesto, Laravel. Aunque cada uno de estos frameworks se fundรณ en principios similares y estรกn orientados a resolver (bรกsicamente) los mismos problemas comunes, sus diferencias clave radican en sus implementaciones. Cada uno tiene sus propias peculiaridades sobre cรณmo abordar la soluciรณn de problemas. Cuando miras el cรณdigo producido por cada uno de ellos, verรกs que hay una lรญnea bastante sรณlida que los separa entre sรญ. En nuestra humilde opiniรณn, el framework Laravel es el mejor.

Mรกs informaciรณn sobre Diferencia entre Laravel y CodeIgniter

Cรณmo descargar e instalar Laravel con Composer

NOTA Se supone que ya tienes una copia de PHP instalada en tu sistema local. Si no, puedes leer cรณmo instalarlo. aqui

Composer es un gestor de paquetes y dependencias. Para instalarlo, abre una terminal y haz clic en cd en un nuevo directorio. Ejecuta este comando:

curl -Ss getcomposer.org/installer | php

Los resultados de este comando se verรกn asรญ:

Descargar e instalar Laravel con Composer

Nota: Para obtener instrucciones mรกs detalladas sobre cรณmo configurar Laravel, consulte la documentaciรณn de Laravel. aqui.

Verรกs que se descarga y compila el script composer.phar, que es el que usamos para instalar Laravel. Aunque hay muchas formas de configurar una nueva aplicaciรณn Laravel, lo haremos a travรฉs del script composer.phar de Laravel. Para instalar este script, ejecuta:

composer global require laravel/installer

Que se verรก algo asรญ:

Descargar e instalar Laravel con Composer

Esto descargarรก e instalarรก todos los archivos del framework, asรญ como todas las dependencias que requiere. Los paquetes se guardarรกn dentro del directorio del proveedor. Una vez que se hayan descargado e instalado, es tan fรกcil como ejecutar el siguiente comando:

laravel new uploadApp

Verรก algo parecido al siguiente resultado:

Descargar e instalar Laravel con Composer

Composer estรก instalando todos los paquetes que Laravel necesita para ejecutarse. Puede tardar unos minutos, asรญ que tenga paciencia. Una vez que haya terminado, ejecute el comando ls -al para ver lo que se instalรณ.

Aquรญ hay un breve desglose de los directorios en una aplicaciรณn Laravel comรบn:

  • aplicaciรณn/: Esta es la carpeta fuente donde reside el cรณdigo de nuestra aplicaciรณn. Todos los controladores, polรญticas y modelos estรกn dentro de esta carpeta.
  • arranque/: Contiene el script de inicio de la aplicaciรณn y algunos archivos de mapas de clases.
  • configuraciรณn/: Contiene los archivos de configuraciรณn de la aplicaciรณn. Por lo general, estos no se modifican directamente, sino que se basan en los valores configurados en el archivo .env (entorno) en la raรญz de la aplicaciรณn.
  • base de datos/: Alberga los archivos de la base de datos, incluidas las migraciones, las semillas y las fรกbricas de prueba.
  • pรบblico/ : Carpeta de acceso pรบblico que contiene recursos compilados y, por supuesto, un archivo index.php
  • recursos/ : Contiene activos de front-end como archivos javascript, archivos de idioma, archivos CSS/SASS y todas las plantillas utilizadas en la aplicaciรณn (llamadas plantillas blade)
  • rutas/ : Todas las rutas de la aplicaciรณn estรกn aquรญ. Hay algunos "alcances" diferentes de rutas, pero en el que nos centraremos es en el archivo web.php.
  • almacenamiento/ : Todos los archivos de cachรฉ temporales utilizados por la aplicaciรณn, archivos de sesiรณn, scripts de vista compilados y archivos de registro
  • pruebas/ : Contiene archivos de prueba para la aplicaciรณn, como pruebas unitarias y pruebas funcionales.
  • proveedor/ : Todos los paquetes de dependencia instalados con Composer

Ahora bien, creemos el resto de la aplicaciรณn y ejecรบtela con un comando artesanal especial (para ahorrarnos la molestia de instalar y configurar un servidor web como Apache o nginx). El archivo .env contiene todos los valores de configuraciรณn que los archivos en el directorio /config utilizan para configurar la aplicaciรณn. En su interior, notarรก que el valor de configuraciรณn para varios parรกmetros utilizados por los componentes internos de la aplicaciรณn.

Diseรฑo de aplicaciones: un rรกpido resumen de nuestros requisitos

En este tutorial en lรญnea de Laravel, crearemos una aplicaciรณn muy simple que harรก solo dos cosas:

  1. manejar la carga de archivos desde un formulario web
  2. mostrando los archivos cargados anteriormente en una pรกgina diferente.

Para este proyecto, nuestra aplicaciรณn serรก de solo escritura, lo que significa que el usuario solo podrรก escribir archivos y ver la lista de archivos que ha subido. Esta aplicaciรณn es extremadamente bรกsica pero deberรญa servirte como una buena prรกctica para empezar a desarrollar tus habilidades y conocimientos de Laravel. Tenga en cuenta que, en aras de la brevedad, he excluido el modelado, las migraciones y la autenticaciรณn de bases de datos pero, en una aplicaciรณn del mundo real, estas son cosas adicionales que deberรก considerar.

Aquรญ hay una lista de componentes que necesitaremos para que la aplicaciรณn funcione como se espera:

  • A ruta que permitirรก que el mundo exterior (Internet) use la aplicaciรณn y tambiรฉn especificarรก el punto final que apuntarรก a donde se encuentra la lรณgica para guardar el archivo cargado.
  • A controlador que maneja la solicitud al flujo de respuesta
  • A plantilla que se utilizarรก para mostrar una lista de archivos cargados anteriormente y el formulario de carga real en sรญ
  • A solicita que el responsable utilizarรก para validar los datos introducidos desde el formulario web

ยฟQuรฉ es una Ruta?

Una ruta en Laravel es bรกsicamente un punto final especificado por un URI que actรบa como un "puntero" a alguna funcionalidad ofrecida por la aplicaciรณn. Por lo general, una ruta simplemente apunta a un mรฉtodo en un controlador y tambiรฉn dicta quรฉ mรฉtodos HTTP pueden acceder a ese URI. Una ruta tampoco siempre significa un mรฉtodo de controlador; Tambiรฉn podrรญa simplemente pasar la ejecuciรณn de la aplicaciรณn a un cierre definido o a una funciรณn anรณnima.

ยฟPor quรฉ utilizar Ruta?

Las rutas se almacenan dentro de archivos en la carpeta /routes dentro del directorio raรญz del proyecto. De manera predeterminada, hay algunos archivos diferentes que corresponden a los diferentes โ€œladosโ€ de la aplicaciรณn (โ€œladosโ€ proviene de la metodologรญa de arquitectura hexagonal). Estos incluyen:

  • web.php El pรบblico orientado a rutas basadas en โ€œnavegadorโ€. Estos son los mรกs comunes y son los que ataca el navegador web. Se ejecutan a travรฉs del grupo de middleware web y tambiรฉn contienen funciones para protecciรณn csrf (que ayuda a defenderse contra ataques y hacks maliciosos basados โ€‹โ€‹en formularios) y generalmente contienen un grado de "estado" (con esto quiero decir que utilizan sesiones)
  • api.php Rutas que corresponden a un grupo de API y por lo tanto tienen el middleware API habilitado de forma predeterminada. Estas rutas no tienen estado y no tienen sesiones ni memoria de solicitudes cruzadas (una solicitud no comparte datos ni memoria con ninguna otra solicitud; cada una estรก autoencapsulada).
  • console.php Estas rutas corresponden a comandos artesanales personalizados que has creado para tu aplicaciรณn.
  • canales.php Registra rutas para transmisiรณn de eventos.

El archivo clave que nos debe preocupar en este momento es el especรญfico del navegador, web.php. Ya hay una ruta definida de forma predeterminada, que es la que selecciona cuando navega a la raรญz web de su aplicaciรณn (la raรญz web estรก en el directorio pรบblico). Vamos a necesitar tres rutas diferentes para que funcione nuestra aplicaciรณn de carga:

  • /upload Este serรก el URI de la pรกgina principal que muestra nuestro formulario web para cargar archivos.
  • /proceso Aquรญ serรก donde el formulario ubicado en el URI /upload publica los datos enviados por el formulario (la โ€œacciรณnโ€ del formulario).
  • /list Esto enumerarรก todos los archivos cargados en el sitio.

nota Es posible que el punto final /list no sea necesario si deseamos poner toda la lรณgica para mostrar el formulario de carga y la lista de archivos en una sola pรกgina; sin embargo, los mantuvimos separados por ahora para agregar un poco mรกs de materia al tema en cuestiรณn. .

//inside routes/web.php
Route::get('/upload', 'UploadController@upload')->name('upload');
Route::get('/download, 'UploadController@download)->name(โ€˜download');
Route::post('/process', 'UploadController@process')->name('process');
Route::get('/list', 'UploadController@list')->name('list');

En este tutorial del marco Laravel, para cada ruta deseada, la enumeraremos explรญcitamente en el archivo de rutas web.php usando uno de los mรฉtodos de solicitud especรญficos de HTTP disponibles (get(), post(), put(), delete(), parche() u opciones() ). Para ver un desglose de cada uno de estos, consulte este vรญdeo afuera. Lo que hacen estos mรฉtodos es especificar quรฉ verbos HTTP pueden acceder a esa ruta determinada. Si necesita una ruta para poder aceptar mรกs de un verbo HTTP (lo que podrรญa ser el caso si estรก utilizando una sola pรกgina para mostrar los datos iniciales y publicar los datos del formulario enviado), puede usar Route::any( ) mรฉtodo.

El segundo argumento para los mรฉtodos Route::get() y Route::post() (y cualquiera de los otros mรฉtodos relacionados con verbos HTTP en la fachada Route) es el nombre de un controlador especรญfico y el mรฉtodo alojado dentro de ese controlador que se ejecuta al llegar al punto final de la ruta con la solicitud HTTP permitida (GET, POST, PATCH, etc.). Estamos usando UploadController para las tres rutas y las hemos especificado de la siguiente manera:

ยฟQuรฉ es una ruta?

El รบltimo mรฉtodo que llamamos en cada ruta es su funciรณn name(), que acepta una sola cadena como argumento y se utiliza para "etiquetar" mรกs o menos una ruta en particular con un nombre fรกcil de recordar (en nuestros casos, cargar, procesar y listar). Me doy cuenta de que no parece una caracterรญstica tan buena darle a cada ruta su propio nombre cuando la URL tiene exactamente el mismo nombre, pero realmente resulta รบtil cuando tienes una ruta especรญfica como /users/profile/dashboard/config, que serรญa mรกs fรกcil de recordar como perfil-admin o usuario-config.

Una nota sobre fachadas:

  • Las fachadas proporcionan una interfaz "estรกtica" para las clases que estรกn disponibles en el contenedor de servicios de la aplicaciรณn".
  • Proporcionan una sintaxis concisa y memorable que le permite utilizar las funciones de Laravel sin recordar nombres de clases largos que deben inyectarse o configurarse manualmente.

En las definiciones de ruta anteriores en este tutorial del marco de Laravel, utilizamos la fachada Ruta en lugar de crear manualmente una instancia de un nuevo objeto Illuminate/Routing/Router y llamar a los mรฉtodos correspondientes en ese objeto. Es solo un atajo que ahorra escribir. Las fachadas se utilizan mucho en todo el marco de Laravel; puedes y debes familiarizarte mรกs con ellas. Los documentos para Fachadas se pueden encontrar. aqui.

ยฟQuรฉ es un controlador?

Un controlador es la โ€œCโ€ de la arquitectura โ€œMVCโ€ (Modelo-Vista-Controlador), en la que se basa Laravel. El trabajo de un controlador se puede resumir en esta sencilla definiciรณn: Recibe la solicitud del cliente y devuelve una respuesta al cliente. Esta es la definiciรณn bรกsica y tambiรฉn los requisitos mรญnimos de cualquier controlador determinado. Lo que hace entre esas dos cosas generalmente se considera la โ€œacciรณnโ€ del controlador (o la โ€œimplementaciรณn de la rutaโ€). Actรบa como el segundo punto de entrada a la aplicaciรณn (el primero es la solicitud) para el cliente, quien envรญa la carga รบtil de la solicitud (que veremos a continuaciรณn) a la aplicaciรณn, esperando algรบn tipo de respuesta (en forma de pรกgina de รฉxito, redireccionamiento, pรกgina de error o cualquier otro tipo de respuesta HTTP).

Un controlador hace (bรกsicamente) lo mismo que una definiciรณn de ruta con una funciรณn anรณnima configurada como "acciรณn" cuando se llega a esa ruta. La diferencia es que un controlador soporta bien la separaciรณn de preocupaciones mientras que una ruta se define en lรญnea con la definiciรณn de URL real, lo que bรกsicamente significa que estamos acoplando el URI asignado a la ruta con la implementaciรณn de la ruta, o el cรณdigo que se ejecuta cuando esa ruta es golpear.

Por ejemplo, los siguientes dos fragmentos de cรณdigo lograrรกn lo mismo:

Ejemplo #1: Definiciรณn e implementaciรณn de la ruta dentro de una sola llamada a un mรฉtodo (en el archivo de rutas web.php)

//inside routes/web.php
<?php
Route::get('/hello-world', function(Request $request) {
   $name = $request->name;
   return response()->make("<h1>Hello World! This is ".$name, 200);
});

Ejemplo #2: La definiciรณn de ruta estรก dentro de route/web.php, pero su implementaciรณn reside dentro de la clase /app/Http/Controllers/HelloWorldController

//inside routes/web.php
<?php

Route::get('/hello-world', 'HelloWorldController@index')->name('hello-world');

------------------------------------------------------------------------------------
//inside app/Http/Controllers/HelloWorldController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;

class HelloWorldController extends Controller
{
   public function index(Request $request)
   {
       $name = $request->name;
       return response()->make("<h1>Hello World! This is ".$name, 200);
   }
}

Aunque el ejemplo n.ยบ 2 de Laravel parece mucho mรกs trabajo (que no lo es, solo un poco mรกs de cรณdigo es todo), observe los beneficios que obtenemos al colocar nuestra lรณgica de acciรณn para la ruta "hola-mundo" dada dentro de un controlador. de con la definiciรณn de la ruta como una funciรณn de devoluciรณn de llamada:

  1. Nuestra lรณgica estรก claramente separada en su propia clase (separaciรณn de preocupaciones)
  2. Nuestro controlador estรก configurado para una extensiรณn posterior si necesitamos agregarle capacidades adicionales... Digamos que tal vez queremos agregar una funciรณn de "adiรณs mundo"... En este caso, cambiarรญamos el nombre del controlador a un "HelloController" mรกs genรฉrico y luego definirรญamos dos mรฉtodos separados, Hola() y el adiรณs(). Tambiรฉn necesitarรญamos definir dos rutas separadas que mapearan el /Hola y el /adiรณs URI a su mรฉtodo apropiado en el controlador. Esto es deseable en comparaciรณn con engordar un archivo de rutas con la implementaciรณn de cada ruta definida como funciones de devoluciรณn de llamada.
  3. Laravel tiene la capacidad incorporada de almacenar en cachรฉ todas las definiciones de ruta en la aplicaciรณn para acelerar el tiempo que lleva encontrar una ruta determinada (aumenta el rendimiento de la aplicaciรณn); sin embargo, solo podrรก aprovechar esto si todas sus rutas definidas dentro de la aplicaciรณn estรกn configuradas usando asignaciones especรญficas del controlador (consulte el Ejemplo #2 arriba)

Ejecutemos este comando que generarรก un nuevo controlador para nosotros.

// ...inside the project's root directory:
php artisan make:controller UploadController   

Bรกsicamente, lo que hace este comando es generar un cรณdigo auxiliar para un controlador llamado "UploadController" dentro del directorio principal del controlador en /app/Http/Controllers/UploadController.php. Siรฉntete libre de abrir ese archivo y echarle un vistazo. Es muy simple porque es sรณlo una versiรณn eliminada del controlador, con la ruta del espacio de nombres correcta y las clases requeridas desde las que se extiende.

Generando la solicitud

Antes de continuar con este tutorial de PHP Laravel y realizar algunos cambios en el stub generado de UploadController, creo que tendrรก mรกs sentido crear primero la clase de solicitud. Esto se debe a que el mรฉtodo del controlador que maneja la solicitud debe indicar el tipo del objeto de solicitud en su firma, lo que le permite validar automรกticamente los datos del formulario entrante (como se especifica en el mรฉtodo rules(). Mรกs sobre eso mรกs adelante...) Por ahora, usemos el comando artisan nuevamente para generar nuestro stub de solicitud:

php artisan make:request UploadFileRequest

Este comando generarรก un archivo llamado UploadFileRequest dentro de app/Http/Requests/UploadFileRequest. Abra el cรณdigo auxiliar y eche un vistazo... Lo encontrarรก muy simple, ya que contiene solo dos mรฉtodos, autorizaciรณn() y reglas.

Creando la lรณgica de validaciรณn

Modifiquemos el talรณn de solicitud para satisfacer las necesidades de nuestra aplicaciรณn. Modifique el archivo para que se vea asรญ:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class UploadFileRequest extends FormRequest
{
   /**
    * Determine if the user is authorized to make this request.
    *
    * @return bool
    */
   public function authorize()
   {
       return true;
   }

   /**
    * Get the validation rules that apply to the request.
    *
    * @return array
    */
   public function rules()
   {
       return [
           'fileName' => 'required|string',
           'userFile' => 'required|file'
       ];
   }
}

No hay muchos cambios, pero observe que el mรฉtodo Authorize() ahora devuelve verdadero en lugar de falso. Este mรฉtodo decide si se permite o no que la solicitud ingrese a la aplicaciรณn. Si se establece en falso, impide que la solicitud ingrese al sistema (que normalmente serรญa un mรฉtodo en el controlador). Este serรญa un lugar muy รบtil para realizar comprobaciones de autorizaciรณn del usuario o cualquier otra lรณgica que pueda decidir si la solicitud puede pasar al controlador. Por ahora, aquรญ simplemente devolvemos verdadero para permitir que cualquier cosa use la solicitud.

El otro mรฉtodo, reglas() es donde entra en juego toda la magia con respecto a la validaciรณn. La idea es simple: devolver una matriz que contenga un conjunto de reglas en forma de:

'formFieldName' => 'constraints this field has separated by pipe characters (|)'

Hay muchas restricciones de validaciรณn diferentes que Laravel admite de manera predeterminada. Para obtener una lista completa de ellas, consulte la documentaciรณn en lรญnea. aquiPara nuestra aplicaciรณn de carga, habrรก dos campos que se pasan a travรฉs de una solicitud POST desde un formulario en el front-end. El parรกmetro fileName debe incluirse dentro del cuerpo del formulario (es decir, es obligatorio) y se utiliza como el nombre de archivo con el que almacenaremos el archivo en el almacenamiento (esto se hace en el controlador; lo abordaremos un poco mรกs adelante). Tambiรฉn especificamos que el nombre del archivo debe ser una cadena agregando un carรกcter de barra vertical (|) y la palabra "cadena". Las restricciones siempre estรกn delimitadas por barras verticales, lo que le permite especificar cualquier criterio adicional para el campo dado en una sola lรญnea. ยกQuรฉ poder!

El segundo parรกmetro, userFile, es el archivo real que el usuario carga desde un formulario en una pรกgina web. UserFile tambiรฉn es necesario y deben ser un archivo. Nota: Si esperรกramos que el archivo cargado fuera una imagen, entonces usarรญamos la restricciรณn de imagen, lo que limitarรญa los tipos de archivos aceptados como uno de los tipos de imรกgenes populares (jpeg, png, bmp, gif o svg). Como queremos permitir que el usuario cargue cualquier tipo de archivo, simplemente mantendremos la restricciรณn de validaciรณn de archivos.

Eso es todo lo que hay que hacer con el objeto de solicitud. Su trabajo principal es simplemente mantener el conjunto aceptable de criterios (restricciones) que los parรกmetros del cuerpo del formulario deben satisfacer para poder avanzar mรกs profundamente en la aplicaciรณn. Otra cosa a tener en cuenta es que estos dos campos (userFile y filename) tambiรฉn deben especificarse dentro del cรณdigo HTML en forma de campos de entrada (con el nombre del campo correspondiente al nombre dentro del objeto de solicitud).

Quizรกs se pregunte: seguro que esto define las caracterรญsticas de lo que debe contener una solicitud de formulario, pero ยฟdรณnde se realiza la verificaciรณn real de estas restricciones? Hablaremos de eso a continuaciรณn.

Modificar el controlador

Abra la aplicaciรณn/Http/Controllers/UploadController y realice los siguientes cambios:

<?php

namespace App\Http\Controllers;

use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Http\Request;
use App\Http\Requests\UploadFileRequest; //our new request class
use Illuminate\Support\Facades\Storage; 

class UploadController extends Controller
{
   /**
    * This is the method that will simply list all the files uploaded by name and provide a
    * link to each one so they may be downloaded
    *
    * @param $request : A standard form request object
    * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
    * @throws BindingResolutionException
    */
   public function list(Request $request)
   {
       $uploads = Storage::allFiles('uploads');

       return view('list', ['files' => $uploads]);
   }

   /**
    * @param $file
    * @return \Symfony\Component\HttpFoundation\BinaryFileResponse
    * @throws BindingResolutionException
    */
   public function download($file)
   {
       return response()->download(storage_path('app/'.$file));
   }

   /**
    * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
    * @throws BindingResolutionException
    */
   public function upload()
   {
       return view('upload');
   }

   /**
    * This method will handle the file uploads. Notice that the parameter's typehint
    * is the exact request class we generated in the last step. There is a reason for this!
    *
    * @param $request : The special form request for our upload application
    * @return array|\Illuminate\Http\UploadedFile|\Illuminate\Http\UploadedFile[]|null
    * @throws BindingResolutionException
    */
   public function store(UploadFileRequest $request)
   {
       //At this point, the parameters passed into the $request (from form) are
       //valid--they satisfy each of the conditions inside the rules() method

       $filename = $request->fileName;    //parameters have already been validated
       $file = $request->file('userFile'); //that we don't need any additional isset()

       $extension = $file->getClientOriginalExtension(); //grab the file extension
       $saveAs = $filename . "." . $extension; //filename to save file under

       $file->storeAs('uploads', $saveAs, 'local'); //save the file to local folder

       return response()->json(['success' => true]); //return a success message
   }
}

Por lo tanto, es un mรฉtodo bastante sencillo para guardar los archivos cargados en el disco. Aquรญ hay un desglose del mรฉtodo upload() anterior:

  • Escriba una pista de la clase de solicitud en el mรฉtodo del controlador que realiza la funcionalidad "carne y patatas" para que podamos validar automรกticamente los datos entrantes.
  • Tome el archivo del objeto de solicitud (ahora validado) dentro del mรฉtodo del controlador (en este caso lo hemos llamado upload() pero tambiรฉn podrรญa haber sido nombrado con un nombre mรกs estandarizado como store()).
  • Saque el nombre del archivo de la solicitud
  • Genere el nombre de archivo final que se utilizarรก para guardar el archivo. El mรฉtodo getClientOriginalExtension() simplemente toma la extensiรณn original del archivo cargado.
  • Almacene el archivo en el sistema de archivos local utilizando su mรฉtodo storeAs(), pasando la ruta nombrada dentro del directorio /storage como primer argumento y el nombre del archivo para guardarlo como segundo.
  • Devolver una respuesta JSON indicando que la solicitud fue exitosa

La plantilla de la hoja

La รบltima pieza importante de este rompecabezas es la plantilla de la hoja, que contendrรก todo el cรณdigo HTML, CSS y JavaScript para nuestra sencilla aplicaciรณn. Aquรญ estรก el cรณdigo. Lo explicaremos mรกs adelante.

<body>
   <h1>Upload a file</h1>
   <form id="uploadForm" name="uploadForm" action="{{route('upload')}}" enctype="multipart/form-data">
       @csrf
       <label for="fileName">File Name:</label>
       <input type="text" name="fileName" id="fileName" required /><br />
       <label for="userFile">Select a File</label>
       <input type="file" name="userFile" id="userFile" required />
       <button type="submit" name="submit">Submit</button>
   </form>
   <h2 id="success" style="color:green;display:none">Successfully uploaded file</h2>
   <h2 id="error" style="color:red;display:none">Error Submitting File</h2>
   <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
   <script>
        $('#uploadForm').on('submit', function(e) {
            e.preventDefault();
            var form = $(this);
            var url = form.attr('action');
            $.ajax({
                url: url,
                type: "POST",
                data: new FormData(this),
                processData: false,
                contentType: false,
                dataType: "JSON",
                success: function(data) {
                    $("#fileName").val("");
                    $("#userFile").val("");
                }
            }).done(function() {
                $('#success').css('display', 'block');
                window.setTimeout(()=>($("#success").css('display', 'none')), 5000);
            }).fail(function() {
                $('#error').css('display', 'block');
                window.setTimeout(()=>($("#error").css('display', 'none')), 5000);
            });
        });
   </script>
</body>
</html>

Esto es lo que nuestro /subir la pรกgina se parece a:

La plantilla de la hoja

Este es un ejemplo muy tรญpico de un archivo blade que contiene un formulario HTML y javascript/jQuery para agregar funcionalidad asincrรณnica (para que la pรกgina no se actualice). Hay un etiqueta sin atributo de mรฉtodo (que explicarรฉ en un segundo) y con un curioso atributo de acciรณn con el valor {{route('file.upload')}}. En Blade, esto es lo que se conoce como una Directiva. Una directiva es simplemente un nombre elegante para una funciรณn: son funciones especรญficas de las plantillas de Blade que realizan diferentes operaciones que son comunes para la construcciรณn de pรกginas web y aplicaciones web. Para comprender mejor todas las cosas interesantes que Blade puede hacer, consulte la documentaciรณn aqui. En el caso anterior, estamos usando la directiva de ruta para generar una URL para el envรญo de nuestro formulario.

Recuerde que definimos nuestras rutas anteriormente en la aplicaciรณn dentro del archivo web.php, especificando un nombre fรกcil de recordar para cada una de ellas. La directiva {{route()}} acepta el nombre de una ruta, lo busca dentro de la lista de rutas almacenadas en cachรฉ internamente y genera una URL completa basada en la definiciรณn de esa ruta en el archivo web.php. Para este primer caso, especificamos que queremos que el formulario envรญe los datos enviados a la URL /proceso de nuestra aplicaciรณn, que se define como un PUBLICAR ruta.

La siguiente cosa extraรฑa que quizรกs hayas notado es la etiqueta @csrf justo debajo de la etiqueta del formulario de apertura. En Blade, esta etiqueta genera un parรกmetro _token en el formulario, que se verifica dentro de la aplicaciรณn antes de que se permita procesar los datos del formulario. Esto garantiza que los datos dentro del formulario tengan un origen vรกlido y evita ataques de falsificaciรณn de solicitudes entre sitios. Para obtener mรกs informaciรณn sobre esto, consulte el documentos.

Despuรฉs de esto definimos nuestro formulario como normal, sin embargo, tenga en cuenta que los nombres de nuestros parรกmetros de formulario, userFile y fileName son los exactamente el mismo como se define dentro de nuestro objeto de solicitud. Si olvidamos incluir una entrada para un parรกmetro dado que estaba definido en el objeto de solicitud (o lo escribimos mal), la solicitud fallarรญa y se devolverรญa un error, impidiendo que la solicitud del formulario original llegue al mรฉtodo del controlador ubicado en UploadController@ proceso .

Continรบe, pruรฉbelo y envรญe algunos archivos a la aplicaciรณn mediante este formulario. Luego, navegue hasta el /lista pรกgina para ver el contenido de la carpeta de carga, con los archivos que cargรณ enumerados en una tabla:

La plantilla de la hoja

The Bigger Picture

Demos un paso atrรกs y veamos lo que hemos hecho en este tutorial de Laravel.

Este diagrama muestra la aplicaciรณn tal como estรก actualmente (sin incluir detalles de alto nivel):

Diagrama del tutorial de Laravel

Debe recordar que el objeto de solicitud que construimos al comienzo de este tutorial de Laravel debe tener los mismos parรกmetros definidos en su mรฉtodo de reglas que en el formulario de la plantilla de hoja (si no, vuelva a leer la secciรณn "Creaciรณn de la lรณgica de validaciรณn"). . El usuario ingresa el formulario en una pรกgina web que se representa a travรฉs de un motor de plantilla Blade (este proceso, por supuesto, estรก en piloto automรกtico, por lo que ni siquiera tenemos que pensar en ello) y envรญa el formulario. El cรณdigo jQuery de la plantilla en la parte inferior detiene el envรญo predeterminado (que redirigirรญa automรกticamente a una pรกgina separada), crea una solicitud ajax, carga la solicitud con los datos del formulario y carga el archivo, y envรญa todo a la primera capa de nuestro aplicaciรณn: la peticiรณn.

El objeto de solicitud se completa asociando los parรกmetros dentro del mรฉtodo reglas() con los parรกmetros del formulario enviado y luego valida los datos de acuerdo con cada regla especificada. Si se cumplen todas las reglas, la solicitud se pasa a cualquier mรฉtodo de controlador que corresponda a los valores definidos en el archivo de ruta web.php. En este caso, es el mรฉtodo Process() del UploadController el que hace el trabajo. Una vez que accedemos al controlador, ya sabemos que la solicitud pasรณ la validaciรณn, por lo que no tenemos que volver a probar si el nombre de archivo proporcionado es, de hecho, una cadena o si el parรกmetro userFile realmente contiene algรบn tipo de archivo... Podemos continuar como normal.

Luego, el mรฉtodo del controlador toma los parรกmetros validados del objeto de solicitud, genera un nombre de archivo completo al concatenar el parรกmetro fileName pasado con la extensiรณn original de userFile, almacena el archivo dentro de un directorio en nuestra aplicaciรณn y luego devuelve un archivo simple codificado en JSON. respuesta verificando que la solicitud fue exitosa. La respuesta es recibida por la lรณgica jQuery, que realiza algunas tareas mรกs relacionadas con la interfaz de usuario, como mostrar el mensaje de รฉxito (o error) durante 5 segundos y luego ocultarlo y borrar las entradas del formulario anterior... esto es para que el usuario lo sepa. para asegurarse de que la solicitud fue exitosa y pueden cargar otro archivo, si asรญ lo desean.

Ademรกs, fรญjate en el diagrama anterior dรณnde se traza la lรญnea entre el cliente y el servidor. Es absolutamente fundamental que entiendas este concepto y te ayudarรก a resolver problemas y cuestiones que puedas tener en el futuro cuando hagas malabarismos, por ejemplo, con mรบltiples solicitudes asincrรณnicas que pueden ocurrir en un momento dado. La separaciรณn estรก justo en el lรญmite del objeto de solicitud. El objeto de solicitud en sรญ puede considerarse como la "puerta de entrada" al resto de la aplicaciรณn... Realiza la validaciรณn inicial y el registro de los valores del formulario que se pasan desde el navegador web. Si se consideran vรกlidos, continรบa hasta el controlador. Todo lo anterior estรก en el front-end (el "cliente" significa literalmente "en la computadora del usuario"). La respuesta se devuelve desde la aplicaciรณn al lado del cliente, donde nuestro cรณdigo jQuery escucha pacientemente su llegada y realiza algunas tareas de interfaz de usuario simples una vez que la recibe.

Hemos cubierto mรกs de 90 preguntas frecuentes importantes. Preguntas de entrevista relacionadas con Laravel y PHP para que los candidatos nuevos y experimentados consigan el trabajo adecuado.

Resumir este post con: