Laravel 6.*
Laravel se ha convertido en el framework php más utilizado para desarrollo web.
En septiembre/2019 se publicón la versión 6.0
Desde entonces usa versionado semántico.
Febrero y agosto: versiones mayores: 6 (LTS), 7, ...
Semanalmente pueden aparecer versiones menores (segundo dígito) y de parcheo (tercero).
Las versiones mayores pueden incluír cambios de ruptura, el resto no.
Usa arquitectura MVC (Modelo Vista Controlador) y mucho más:
Sistema de enrutamiento potente
Usa Blade como gestor de plantillas
Su propio ORM: Eloquent
Y muchos otros componentes que lo hacen muy interesante: Query Builder, Database Migrations, Seeders, Passport, Dusk, Socialite, ... y muchos otros componentes brindados por terceras partes.
Enlaces:
Wikipedia mejor en inglés.
Laracast: videotutoriales oficiales
Styde.net: numerosos videotutoriales, cursos y publicaciones
Código fuente. Se puede clonar para iniciar proyecto.
Instalación
Requisitos:
php7.2 y algunos complementos
Composer como gestor de dependencias
Podemos desarrollar sin servidor o con él (Apache on Nginx)
Podemos dockerizar el entorno de desarrollo
Instalación via composer (directorio blog):
O partiendo del código de GitHub:
Se puede probar ejecutando:
Usando docker y nuestro entornods:
Descargamos nuestro entornods y nos ponemos en la rama laravel
Añadimos al fichero hosts:
Levantamos nuestro servicio:
Colocamos nuestro Laravel limpio en data/laravel
¿Cómo?
OPCION 1 (composer)
Levantamos nuestro entornods.
nota: hay que cambiar los permisos de data/laravel a 777.
Entramos en el contenedor laravel:
Ya podemos acceder a http://laravel.local
OPCION 2 (git + composer)
Clonamos el código desde https://github.com/laravel/laravel.git o desde nuestro repositorio.
Lo hacemos en el directorio
entornods/data/laravel
El directorio de partida puede ser
git@github.com:laravel/laravel.git
o el de nuestro proyecto particular
OJO!!!
El entornods viene configurado para una aplicación ubicada en data/laravel
El resto de instrucciones también
Si usamos otro nombre deberemos ajustar alguno de estos comados y el contenido del fichero docker-compose.yml
Entramos en el contendor laravel y ejecuamos un par de comandos:
Vamos al navegador con la url http://laravel.local
El uso de la consola va a ser importante en el desarrollo con Laravel
Es muy recomedable definir aliases de comandos pero mucho más si usamos docker
Editamos el fichero ~/.bashrc
ejecutar lo siguiente si no queremos reiniciar:
El fichero
.env
El fichero .env define variables utilizadas únicamente en el entorno de desarrollo.
Cada sitio de desarrollo o producción mantiene su propio
.env
Este fichero debe excluirse de git. Compruébalo en el fichero .gitignore.
Debemos ajustar la parte de BBDD y el APP_URL=http://laravel.local
El directorio de configuración es config. Buena parte de la configuración es condicionada al contenido del fichero
.env
Repositorio de clase
Vamos a usar el repositorio: laravel19
Recomendación: hacer un fork del mismo:
Ve a bitbucket y realiza un fork
Clona dentro de
entornods/data
tu repositorioInstalar dependencias.
Obten una copia del fichero
.env
Ejecuta (recuerda que laraa es un alias):
Es interesante poder descargar el código de clase:
Arquitectura
Configuramos nuestro servidor para que todas las peticiones lleguen a index.php (var https://laravel.com/docs/6.x/installation)
index.php sólo crea un objeto $app a partir del script bootstrap/app.php.
Tras esto la petición o request se pasa al kernel (nucleo) http o de consola:
Kernel Http:
Carga clases bootstrapers que preparan la aplicación (heredado)
Define una serie de middlewares (filtros) que se ejecutan antes de tratar el request
Por fin, el kernel trata el request y devuelve un response (heredado)
Todas las clases dentro de Iluminate están dentro de vendor, son parte del framework y no debemos modificarlas en absoluto. Todo lo "heredado" está ahí.
La respuesta
Tras preparar la aplicación, la petición se pasa al router
De acuerdo a las rutas definidas se genera una respuesta o se delega en un controlador.
A las rutas y controladores se les puede asignar middlewares.
Los Service Providers
Son el elemento clave en el arrange (bootstraping) de la aplicación.
Definen los componentes disponibles en la aplicación.
El fichero
config/app.php
cuenta con un array donde definimos cuales otros queremos usarMuchos de ellos están en el frameword (empiezan por Illuminate)
Otros están en app/Providers
Si añadimos librerías o creamos los nuestros propios (avanzado) deberemos añadir elementos a este array.
Rutas
En nuestro framework mvc "casero", un controlador era responsable de una tarea concreta, o conjunto de tareas relacionadas entre sí (CRUD sobre una tabla, por ejemplo).
Para nosotros el path o ruta de nuestra url representaba /controlador/metodo/arg1/arg2/argN.
Laravel tiene un sistema de enrutado mucho más flexible y potente.
Las rutas se definien en el directorio
routes
:web.php
define todas las rutas de la aplicación webapi.php
define las rutas asociadas a un servicio web RESTfulconsole.php
define rutas usadas desde la consola conphp artisan
channels.php
se usa en aplicaciones en tiempo real y websockets. No toca...
Para definir una ruta usamos una clase llamada Route.
Usamos una función que define el tipo de petición (get, post, ...)
Definimos una ruta
Definimos una función de callback o como veremos un controlador y un método
Veamos algunos ejemplos ilustrativos:
Rutas resource: REST
Un CRUD necesita definir 7 rutas para 7 acciones.
Si definimos rutas de tipo resource se mapearán estas 7 rutas.
En la medida de lo posible estas rutas siguen el paradigma REST.
Son las acciones necesarias para un CRUD completo y usando los distintos verbos HTTP: get, post, put y delete.
Para ver como gestionar estas rutas y este tipo de controladores: https://laravel.com/docs/6.x/controllers#resource-controllers
Definición de una ruta
Creación de un controlador resource:
Lista de rutas:
Verb
URI
Action
Route Name
</tr>
</thead>
GET
/photos
index
photos.index
</tr>
GET
/photos/create
create
photos.create
</tr>
POST
/photos
store
photos.store
</tr>
GET
/photos/{photo}
show
photos.show
</tr>
GET
/photos/{photo}/edit
edit
photos.edit
</tr>
PUT/PATCH
/photos/{photo}
update
photos.update
</tr>
DELETE
/photos/{photo}
destroy
photos.destroy
</tr>
</tbody>
</table>
</small>
No siempre nos vale el uso de rutas resource.
Si queremos definir una ruta y un método la sintaxis es:
Para otras cuestiones leer la documentación:
Uso de middlewares
Definir rutas resource con except/only methods
Asignar nombres a rutas
...
MVC
Laravel es mucho más que una arquitectura MVC
No obstante esta es una parte fundamental del framework
Controladores
Su ubican en app/Http/Controllers (Podríamos usar subdirectorios)
Para crear un controlador usaremos:
Deberemos definir los métodos que necesitemos y asociarlos a una ruta del fichero de rutas (web.php).
Si queremos usar rutas de tipo resource:
Ya nos vendrá con los 7 métodos asociados a una ruta resource
OJO! Los formularios HTML no pueden usar PUT, PATCH ni DELETE. Podemos usar campos ocultos para falsear los vervos. El metodo helper
method_field
lo puede hacer por nosotros:
Si en un método necesitamos hacer uso del objeto $request debemos incluírlo en su cabecera con type hinting:
Vistas: Blade
Las vistas en php: php + html ==> código poco claro.
Mejor motores de plantillas que facilitan la inclusión de contenido variable en nuestro html.
Motores de plantillas son:
Blade, usado por Laravel
Smarty, muy habitual, no ceñido a ningún framework
Twig, usado por Simphony.
Código más limpio.
En laravel se devuelven con la función helper view()
Desde un controlador o ruta:
Buscará una vista en el directorio resources/views/grupo
El fichero se llamará vista.blade.php o vista.php
Para llevar variables a la vista debemos hacer lo siguiente:
Ejemplos:
Existen otras variantes:
Con with:
Y por último usando compact.
Modelo
Bases de datos
Para acceder a bases de datos podemos (por orden):
ORM: Eloquent. Usado por Laravel y que usa una arquitectura Active Record.
Fluent Query Builder. Un sistema de creación de consultas independiente del gestor de bbdd utilizado.
SQL. Usar consultas de Raw Sql (sql en crudo o a pelo). Poco habitual
Bases de datos compatibles:
MySQL
Postgres
SQLite
SQL Server
Configuración:
Fichero config/database.php.
Pero basada en el .env.
Podemos usar las bases de datos de forma convencional, creadas previamente.
Más interesante usar migraciones como veremos.
Modelo
Las clases modelo extienden una superclase llamada Model
Heredan métodos muy interesantes.
Permiten realizar multitud de operaciones sin escribir una sóla línea de código a través de Eloquent.
Nomenclatura:
El nombre del modelo: tiene que ser en singular y mayúscula. P.ej. "User"
La la tabla asociada estará en plural y minúscula. P. ej. "users"
Clave primaria por defecho "id".
Eloquent usa las columnas created_at y updated_at para actualizar automáticamente esos valores de tiempo.
Artisan nos ayuda a crear los modelos:
La migración es un fichero que nos permite ir creando a la BBDD a nuestra medida
Método up: crea o modifica una tabla
Método down: retrocede los cambios o borra la tabla
Si queremos cambiar los parámetros por defecto respecto a nombre de tabla, clave primaria y uso de columnas temporales:
Veamos un ejemplo de CRUD Study. Vamos a ver el código de las clases Study y de StudyController.
Clase modelo. Muy sencillo porque Eloquent nos provee de los métodos que necesitamos.
Clase modelo. Usamos los métodos que nos facilita Eloquent como son:
El controlador:
Response
Podemos reenviar la respuesta de diferentes modos:
Reenvio a una ruta concreta:
Reenvío a rutas con nombre o con URL:
Reenvío a la misma ruta de la que venimos, e incluso añadir mensajes de error:
Reenviar a un método de un controlador:
Migraciones y Seeders
Migraciones
Laravel provee un sistema llamado "migraciones" que permite elaborar la estructura de la base de datos de un modo paulatino.
Las migraciones se asemejan a un control de versiones para la base de datos. Cada migración puede desplegarse o deshacerse según se precise.
Facilitan enormemente el trabajo en equipo y mediante SCV (git u otro).
Facilitan la migración de SGBD.
Facilitan la implantación en nuevos equipos de desarrollo o en producción.
Debemos crear una migración por cada tabla.
Debemos crearla con artisan y editarla después.
Nota, en la versión 6 podemos crearla a la vez que el modelo:
Ejemplo de migración de la tabla studies:
Para modificar una tabla tenemos dos opciones:
Modificar la migración de creación. NO SIEMPRE POSIBLE
Crear una migración de modificación. Ejemplo:
Ejecutar migraciones
*
Las migraciones se gestionan desde la consola mediante comandos de artisan.
El comando base es
php artisan migrate
. En los siguientes apartados vamos a ver las variantes.
Creación de migraciones
Se usa
artisan make:migration
:El resultado es una clase hija guardada database/migrations
El fichero se nombra usando el timestamp de creación para que sea ejecutado en el orden correcto.
Métodos de una migración
up() sirve para modificar la base de datos. Típicamente crear una tabla.
down() sirve para devolver la base de datos a su estado previo. Típicamente borrar una tabla.
Código de las migraciones
Dentro de las funciones up y down usamos las funciones de la clase esquema para:
Crear tablas:
Schema::create('nommbreTabla', 'funcion_closure');
Renombrar tablas:
Schema::rename\($original, $nuevo\);
Borrar tablas:
Schema::drop('users');
oSchema::dropIfExists('users');
Modificación de tablas:
Schema::table('nommbreTabla', 'funcion_closure');
En las funciones anónimas (closure) de creación y modificación podemos hacer prácticamente cualquier cosa que soporte SQL. Debemos usar los métodos de la clase Blueprint aplicados a la variable $table:
Los posibles modificadores son:
Para otras operaciones consultar la documentación oficial.
Seeders (o sembradores)
Los seeders son clases usadas para:
Rellenar las tablas con datos de prueba
Cargar las tablas con datos iniciales.
Creación con artisan:
php artisan make:seeder StudySeeder
Los seeders tienen un método run() donde se registra el contenido de los registros a insertar. Puede usarse sintáxis de Query Builder o de Eloquent
Ejemplo:
El orden en que se ejecutan los seeders se establece manualmente. Debe rellenarse el método run() de la clase DatabaseSeeder ubicada en database/seeds
Su ejecución es desde artisan:
Modo general
php artisan db:seed
Junto a las migraciones:
php artisan migrate:refresh --seed
De forma individual
php artisan db:seed --class=ModuleSeeder
Model Factories
Crear un factory:
Codificar un factory:
Usar el factory:
Crear un objeto con
make()
o concreate()
, el primero crea una variable, el segundo además la guarda en base de datos:
Podemos crear más de un registro en la misma orden:
Además podemos fijar o sobreescribir el valor de los campos:
Middleware
Los middleware son filtros que se ejecutan antes de que el control pase a una ruta o a un controlador.
Podemos asciar un middleware a una ruta:
O a un controlador, en su constructor:
kernel.php
En el kernel.php de la aplicación se definen varias cuestiones relativas a los middleware.
Un grupo de middleware que se aplican a todas las peticiones. Atributo $middleware.
Se asignan nombres a los middleware para ser usados en las rutas. Atributo
$routeMiddleware
.Dos grupos de middleware:
web que se aplica a todas las rutas definidas en el fichero de rutas web.php
api que se aplica a las rutas del fichero api.php
Ejemplos de middleware
CheckForMaintenanceMode Se aplica a todas las rutas. Se activa su funcionalidad con los comandos:
Después de down genera un error 503
Comprueba la existencia del fichero /storage/framework/down
Down crea el fichero, up lo borra.
Vamos a ver los que se aplican a todas las peticiones web.
EncryptCookies. Encripta las cookies
AddQueuedCookiesToResponse. Añade las cookies creadas mediante el método
Cookie::queue($micookie)
;StartSession. Inicia sesión de forma automática.
ShareErrorsFromSession Hace visible el objeto errors tras la validación.
VerifyCsrfToken. Verifica los token CSRF.
SubstituteBindings ¿?
Además, dispondemos de los siguientes definidos en route:
auth. Pasa el filtro si estás autenticado.
guest. Pasa el filtro si no has hecho login
can. Filtro usado para autorización.
throttle. Limita el número de peticiones por minuto aceptadas desde un host determinado.
Construir un middleware:
Usamos artisasn:
Código.
La lógica está en la función handle.
Si se dan las condiciones adecuadas se pasa el filtro (
return $next($request);
)Si no se dan las condiciones abortar o redirigir.
Registrar el middleware en el kernel dentro de $routeMiddleware
Ya podemos usarlo como el resto:
Sesiones y Autenticación
Autenticación
Ya vimos como añadir el sistema de autenticación propio de Laravel
Disponde de un juego de migraciones, rutas, controladores y vistas que hacen posible la gesión de usuarios
Documentación oficial: https://laravel.com/docs/6.x/authentication
Autenticarse es identificarse, que la apliación nos reconozca como un usuario concreto.
Para hacerlo debemos hacer uso de variables de sesión.
Laravel viene con un sistema base muy completo. Para instalarlo (v5 es distiono!!):
Las vistas generadas están construidas con Twiter Bootstrap y se almacenan en el directorio: resources/views/auth.
Rutas:
Para login se usa
/login
Tras el login se usa
/home
. Puede personalizarse en el LoginController.Por defecto el nombre de usuario es su e-mail.
Para cerrar la sesión:
logout
Para resetear la contraseña:
password/reset
Para el reseteo de contraseñas se envia un correo con un token.
Para pasar los mails a log y no enviar realmente:
En el fichero
.env
cambiar el parámetro: `MAIL_DRIVER=log`
Completar en config/mail.php:
Los correos se guardan en storage/logs
Podemos ver el correo enviado para resetear contraseña
Si queremos acceder a la información del usuario actual debemos usar la clase fachada Auth.
Sesiones
Los parámetros de configuración de sesiones se definen en
config/session.php
.Importante es el almacenamiento y el tiempo de vida de la sesión.
Con Laravel no es preciso usar directamente la variable $_SESSION.
ni debemos usar las funciones session_start() o session_destroy()
Podemos acceder a un dato guardado en sesión de tres modos:
El request, esto requiere inyección de dependencias:
La fachada Session
La función helper session():
Obtener todos los datos de una sesión
Podemos guardar datos en sesión de dos modos:
Podemos eliminar datos de sesión:
Guardar datos sólo durante una petición (request) sólamente.
Esto se usa en validaciones de forma automática, transparente al usuario
Para los datos antiguos (old)
Para los mensajes de error
Autorización: reglas y políticas
Laravel nos brinda dos sistemas para autorizar acciones: reglas y puertas.
Reglas
Las reglas se definen asociadas a la clase Gate.
Son una solución más simple.
Políticas
Son soluciones más elaboradas que engloban la autorización referida a un modelo concreto.
Se definen en clases dentro guardadas en app/Policies
Tienen una analogía a rutas y controladores, simpliciad vs complejidad y orden.
En un proyecteo usaremos una u otra (o ambas) de acuerdo a su complejidad y envergadura.
Definir reglas
Las reglas se definen en el AuthServiceProvider.php, dentro de su función boot.
Podemos definir una regla con un closure (función anónima) dentro de dicho método:
Usar reglas
Para comprobar las reglas debemos usar la fachada Gate y alguno de sus métodos (allows, denies). Lo podemos hacer en la propia ruta o más correctamente en el controlador o en un middleware:
Observa que el $user no es pasado a la clase Gate, toma el autenticado. Si quisieramos pasarlo debemos hacerlo así:
Políticas
Si el proyecto es pequeño la solución anterior es válida pero para algo grande puede no ser una buena solución.
Las políticas separan código para no sobrecargar el código del AuthServiceProvider.
Las políticas son clases guardadas en app/Policies y que se crean así:
Tras crear las políticas, éstas deben ser regitradas en el AuthServiceProvider:
Escribiendo las políticas:
Podemos crear los métodos que necesitemos. Por ejemplo el método update lo podemos usar para actualizar un objeto del modelo afectado. Sus argumentos deben ser el user y un objeto del modelo protegido:
El método before permite tomar decisiones generales sin evaluar la política
TODO:
Test
Modelos y BBDD
Errores
Eloquent & Query Builder
Relaciones
Multi Idioma
Ajax
Paginación
Mail
Pdf
Trabajo
Last updated