Conociendo a Laravel 9 — Un framework poderoso.
Empecemos por preguntarnos, sabemos que es un framework? Para evitar confusiones, vamos a definirlo. La palabra framework en español se traduce en “entorno de trabajo”, y se define como un conjunto de conceptos, prácticas y criterios que permiten abordar un área, problemática o proceso.
En el desarrollo de software aplicamos este concepto para ciertas herramientas que ponen a disposición un conjunto de operaciones preconstruidas (a veces llamadas plantillas), y a su vez definen ciertas reglas que facilitan la construcción de procesos generales de las aplicaciones.
En ese orden de ideas, pensemos en un framework que nos facilite operaciones como: conexiones a base de datos, construcción de modelo de datos, presentación de datos a partir de templates, construcción de APIs (recordar lo visto en nuestro texto de bases de backend), por nombrar un conjunto común de operaciones de cualquier aplicación.
Ya teniendo una idea de lo que seria un framework, pasemos a hablar de frameworks en PHP. En este caso un framework en PHP nos va a facilitar la construcción de sistemas bajo este lenguaje de programación. Existen diferentes opciones, tales como: Symphony, Cake, Codeigniter y Laravel.
Qué es Laravel?
Hablemos entonces de Laravel, en su versión más reciente la 9.x, empecemos por entender que es Laravel. Del sitio web: https://openwebinars.net/ tomamos su definición:
Laravel es un framework de PHP para ayudarnos en un tipo de desarrollo sobre aplicaciones escritas en este lenguaje de programación. Esté framework nos ayuda en muchas cosas al desarrollar una aplicación, por medio de sus sistema de paquetes y de ser un framework del tipo MVC (Modelo-Vista-Controlador) da como resultado que podamos “despreocuparnos” (por así decirlo) en ciertas aspecto del desarrollo, cómo instanciar clases y métodos para usarlos en muchas partes de nuestra aplicación sin la necesidad de escribirlo y repetirlos muchas veces con lo que eso conlleva a la hora de modificar algo en el código.
De la definición anterior podemos inferir que Laravel tiene un target o segmento de aplicaciones donde se comporta mejor, que es la gestión de modelos de datos, facilitándonos las operaciones de CRUD (Create, Read, Update e Delete o Crear, Leer, Actualizar y Borrar).
Ahora y como llegamos a usar Laravel?
Instalando Laravel
Para hacer uso de Laravel y aprovechar sus características, debemos instalarlo, para ello hay que tener algunos pre-requisitos como:
- Servidor Web: Apache o Ngix
- PHP v8.x o superior, en el caso de usar Laravel, su última versión.
- Composer, gestor de paquetes de php.
En el artículo: Bases para BackEnd, están los pasos para instalar Apache y usarlo como servidor web y en artículos Bases de PHP están los pasos hacer la instalación de PHP. Para instalar composer les recomiendo la documentación oficial que puedes encontrar en este link.
Luego de tener los prerequisitos, los siguientes pasos son relativamente sencillos, va a depender de como queremos trabajar, podemos instalar Laravel y luego crear diferentes proyectos o podemos crear proyectos basados en Laravel. Para nuestro ejercicio vamos a seguir la segunda opción, creamos un proyecto basado en Laravel de la siguiente forma:
composer create-project laravel/laravel nombre-app
En la anterior línea de comando, solo debemos cambiar nombre-app por el nombre de nuestra aplicación, recomendación usar siempre minúsculas, no usar caracteres especiales ni espacios, en realidad si usas espacios, probablemente sea creado un proyecto con la primera palabra o frase antes del espacio.
Características de Laravel
Laravel posee un conjunto de características que lo hacen poderoso, versatil y funcional, entre ellas están:
- Implementación eficiente del modelo MVC. Laravel define forma bien marcada las capas: Modelo — Vista y Controlador, esto permite implementar aplicaciones de forma ordenada y eficiente, para cada capa existe una herramienta que facilita su construcción.
- El motor de plantillas blade. Mediante el motor de plantillas blade, se implementa la capa de vistas. El de fácil uso pero a su vez permite implementar de forma funcional todo lo relacionado a la presentación en Laravel.
- El gestor de ORM Eloquent. Gracias a Eloquent, es posible modelar o construir la capa de modelo de forma rápida y eficiente. Eloquent permite implementar modelos de entidades y hacer la interacción con la capa de datos de forma simple.
- Artisan, herramienta de comandos. Con artisan podemos realizar la mayoría de operaciones comunes para incorporar elementos a nuestra aplicación, ej: crear un modelo para una entidad, definir una tabla de nuestra aplicación, actualizar una versión de base de datos, por citar algunas.
- Artquitectura modular y extensible. La estructura de directorios de Laravel es bien intuitiva y está organizada de forma tal que sea de fácil escabilidad, las capas MVC están bien identificadas, esto nos permite hacer más eficiente el desarrollo.
- Soporte multi-idiomas. Por su arquitectura, es bien simple poder hacer que nuestra aplicación sea capaz de manejar o presentarse en múltiples idiomas, ya que tiene una implementación de internacionalización bastante fácil de usar.
- Comportamiento fullstack y backend. Laravel puede ser usado como herramienta de backend, mediante la implementación de sus funcionalidades como una API REST, de forma tal que todos los procesos sean invocados o consumidos a través de protocolo http, usando los verbos de definidos por una API, pero también por implementar capa de vista, Laravel puede ser usado como herramienta FullStack, pues es posible también implementar el front-end de forma sencilla.
Construyendo una aplicación de gestion de empleados en Laravel
Vamos a implementar el modelo de datos que definimos en nuestro artículo de Nociones de base de datos, allí definimos 2 entidades de información: Empleados y Proyectos. Definimos una relación entre ellas para conocer cuales empleados estaban involucrados en que proyectos. Vamos a implementarlo con Laravel.
Ejecutemos el paso a paso.
Crear el proyecto
Vamos a la consola y ejecutamos el siguiente comando, tal como lo vimos anteriormente, sólo que esta vez le damos el nombre correspondiente:
composer create-project laravel/laravel gestion-proyectos
El proyecto debe ser creado con un usuario que tenga permisos de realizar esta operación en el directorio correspondiente y que sea accesible por el servidor web.
Si todo es correcto, debe aparecer una imagen como la que sigue:
Vamos a verificar que todo esté correctamente funcionando. En nuestro caso vamos a configurar un directorio virtual dentro de apache para nuestros proyectos Laravel, dentro de /var/www/laravel, luego vamos al archivo de configuración de apache y agregamos su configuración correspondiente (esto es igualmente valido en Windows, solo tener cuidado en las rutas, que probablemente serán C:\xampp\apache\htdocs)
Analicemos la estructura de directorios y vamos reconocer las capas que conversamos anteriormente:
- public: es el único directorio accesible desde el navegador, es allí donde Laravel comunica con el mundo.
- app: En este directorio está el código necesario de las capas Modelo y Controlador. Dentro de app vas a conseguir, el directorio
models
encargado de los modelos de las entidades y el directorioHttp
donde está la lógica de negocio o capa controladora. - config: El directorio de configuración, como su nombre lo indica, contiene todos los archivos de configuración de su aplicación. Siendo el archivo
app.php
el que contiene la configuración base de la aplicación. - database: Aquí se almacenan los scripts que permiten realizar operaciones sobre la base de datos, en el directorio migrations es posible realizar operaciones de creación y actualización de la estructura de la base de datos, en el directorio seeders puedes crear scripts que alimenten con los datos iniciales tu aplicación.
- lang: En este directorio almacenamos los mensajes o textos de acuerdo a los idiomas en que nuestra aplicación va a trabajar.
- resources: Almacena la capa de las vistas, tanto las plantillas, como los archivos de estilos y scripts de JS
- routes: Contiene las definiciones de las rutas de nuestra aplicación, toda opción o proceso se trata como una ruta. Podemos tener rutas que van a ser tratadas y resueltas en modo fullstack (es decir que respondemos código HTML) y podemos tener rutas que serán respondidas en modo backend, es decir que Laravel se comporta como una API Rest.
- storage: en esta ubicación se almacenan archivos generados a partir del uso de la aplicación, entre ellos archivos de sesión, archivos de seguimiento, cache para mejora de la velocidad de respuesta y archivos que el usuario haya cargado.
- test: este es el directorio de pruebas automatizadas.
- vendor: El directorio contiene sus dependencias de Composer.
Creando las tablas de la aplicación
Para crear la capa de datos, en este caso las tablas de la base de datos relacional de nuestra aplicación, usamos el interprete de comando artisan, de la siguiente forma:
php artisan make:migration create_nombre_tabla
Luego de ejecutado esto vamos database/migrations y vamos a observar un archivo .php con la fecha y hora de creación + el nombre que indicamos.
Podemos generar tantas tablas como sean necesarias, pero este proceso aún no se ha finalizado, en realidad apenas hemos hecho el proceso de llamar a la generación de las tablas.
En los scripts que se han creado, debemos entrar y actualizar el código de forma tal que podamos incluir los campos necesarios.
Podemos ver un ejemplo de archivo de creación de tablas completo, tomando el archivo: 2014_10_12_000000_create_users_table.php
y verificando su contenido:
Observa que con el objeto $table
podemos definir que tipo de campo vamos a crear. Es posible ver los tipos de datos válidos para los campos en Laravel mediante el siguiente link.
Creando las entidades de información
Laravel ofrece una forma simple de crear entidades de información, que son los modelos que van a gestionar la capa de datos que definimos en el paso anterior.
Para crear un modelo, en el directorio raíz de nuestra aplicación, basta con ejecutar el siguiente comando:
php artisan make:model <Nombre>
En nombre colocamos como se llama nuestro modelo, en nuestro caso vamos a crear el modelo de Empleado
entonces colocamos de la siguiente forma:
php artisan make:model Empleado
Realizado este proceso, será generado un archivo dentro de la carpeta /app/Models/
con el nombre de Empleado.php, este archivo tendrá el esqueleto para nosotros definir los campos.
Ejemplo del modelo de Empleado según nuestra capa de datos:
<?phpnamespace App\Models;use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;class Empleado extends Model
{
use HasFactory;protected $fillable = [
'dni',
'nombre',
'apellido',
'direccion',
'email',
'telefono'
];
}
Entiendiendo sobre rutas en Laravel
Ya con nuestro modelo definido, tenemos lo necesario para poder avanzar en el proceso de realización de nuestro CRUD, solo que debemos realizar la comunicación entre la capa de la vista (View) y la capa de datos, para ello, vamos a definir lo que se denominan Rutas, que es la forma de indicarle a Laravel como implementar la capa de negocios (Controlador) a partir de ciertos eventos.
En Laravel tenemos la posibilidad de definir rutas tanto para el comportamiento FullStack como para el comportamiento de BackEnd puro, y de acuerdo a lo necesario, la ruta se define en un archivo u otro. En nuestro caso vamos a avanzar de la forma FullStack, en ese caso el archivo de rutas que debemos usar es routes/web.php
Para nuestro ejemplo debemos definir rutas que realicen las siguientes acciones:
- Mostrar la lista de registros de nuestro modelo: Empleados
- Permitir agregar un nuevo registro
- Visualizar el detalle un registro
- Editar los datos de un registro existente
- Borrar cualquier registro.
Todas acciones descritas anteriormente son responsabilidad de la capa controladora, que va a conectar los datos (modelo) con la interfaz (vista).
Para cada una de las acciones a realizar, debemos indicar el modo de transporte de datos o el verbo a utilizar, cuando trabajamos o implementamos un CRUD los verbos a utilizar se definen de esta forma:
- Consulta de registros, ya sea múltiple o de un registro en detalle usamos el verbo GET
- Para insertar un nuevo modelo, usamos el verbo POST
- Cuando deseamos actualizar un registro completo, aplicamos el verbo PUT.
- En caso de querer sólo actualizar alguna parte específica del modelo, usamos el verbo PATCH
- Para eliminar un registro usamos el verbo DELETE
Dicho esto, nuestro archivo de rutas queda de la siguiente forma, siendo necesario implementar toda la lógica en el controlador (tema que veremos más adelante):
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\EmpleadoController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('app');
});
//Lista de registros
Route::get('/empleados', [EmpleadoController::class,'index'])->name('empleados.index');
//Creación de registros
Route::get('/empleados/create', [EmpleadoController::class,'create'])->name('empleados.create');
//Insertar registros
Route::post('/empleados', [EmpleadoController::class,'store'])->name('empleados.store');
//Detalle de registros
Route::get('/empleados/{id}', [EmpleadoController::class,'show'])->name('empleados.show');
//Editar registros
Route::get('/empleados/edit/{id}', [EmpleadoController::class,'edit'])->name('empleados.edit');
//Actualizar registros
Route::put('/empleados/{id}', [EmpleadoController::class,'update'])->name('empleados.update');
//Borrar registros
Route::delete('/empleados/{id}', [EmpleadoController::class,'destroy'])->name('empleados.destroy');
Implementando un controlador para nuestro modelo
Para atender las operaciones entre la capa de datos y la interfaz del usuario, debemos implementar el responsable por la lógica de negocios. Ese responsable es la capa controladora. En Laravel tenemos la opción de crear controladores simples, invocables o de recursos. El primer caso el controlador se crea con la estructura mínima, en el segundo el controlador va a ser responsable de una labor o acción compleja y en el tercer caso el controlador es responsable de modelo de información.
Para crear un controlador basta con ejecutar lo siguiente:
php artisan make:controller <nombreController>
Si deseamos indicar que es un controlador invocable lo definimos como:
php artisan make:controller <nombreController> --invokable
Ahora si queremos crear un controlador para un modelo (o de recurso) hacemos lo siguiente:
php artisan make:controller <nombreController> --resource
Siguiente la línea de nuestro ejemplo, creamos el controlador de la siguiente forma:
php artisan make:controller EmpleadoController --resource
Y al finalizar esta operación, será creado un archivo en app/Http/Controller/EmpleadoController.php
Este archivo contendrá el esqueleto de operaciones de un controlador relacionado a un modelo, estas operaciones son:
- index: mostrar la lista de elementos del modelo
- create: presentar el formulario de creación de registros.
- store: crear registros nuevos en la base de datos
- show: mostrar el detalle de un registro
- edit: presentar un formulario para actualización de datos existentes.
- update: actualizar en base de datos los datos de un registro
- destroy: borrar un registro.
Como quedaría nuestro controlador, luego de implementado? Quedaría como sigue:
<?phpnamespace App\Http\Controllers;use App\Models\Empleado;
use Illuminate\Http\Request;class EmpleadoController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
//
$data = Empleado::latest()->paginate(5);
return view('empleados.index', compact('data'))->with('i', (request()->input('page',1)-1)*5);
}/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
//
return view('empleados.create');
}/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
//
$request->validate([
'dni'=>'required',
]);$empleado = Empleado::create([
'dni' => $request->dni,
'nombre' => $request->nombre,
'apellido' => $request->apellido,
'direccion' => $request->direccion,
'email' => $request->email,
'telefono' => $request->telefono
]);
return redirect()->route('empleados.show', ['id' => $empleado->id]);
}/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
return view('empleados.show',[
'data' => Empleado::findOrFail($id),
]);
}/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
//
return view('empleados.edit', [
'data'=>Empleado::where('id',$id)->first()
]);
}/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$request->validate([
'dni'=>'required',
]);
//
Empleado::where('id',$id)->update([
'dni' => $request->dni,
'nombre' => $request->nombre,
'apellido' => $request->apellido,
'direccion' => $request->direccion,
'email' => $request->email,
'telefono' => $request->telefono
]);return redirect()->route('empleados.show', ['id' => $id]);
}/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
Empleado::findOrFail($id)->delete();
return redirect()->route('empleados.index');
}
}