Está en la página 1de 86

“Año de la unidad, la paz y el desarrollo”

UNIVERSIDAD NACIONAL DEL SANTA

E.A.P: INGENIERÍA DE SISTEMAS E INFORMÁTICA

ASIGNATURA: APLICACIONES DISTRIBUIDAS

DOCENTE: CAMILO E. REBAZA

TEMA: LARAVEL EN FUNCIONAMIENTO DE UN MARCO PARA


CREAR APLICACIONES PHP MODERNAS- RESUMEN 1-5

ESTUDIANTE:
FLORES MENDOZA MANUEL
TAPIA ESPINOZA JHORDAN
VALERIO PACHECO JHENDER
VILLAVICENCIO TORRES AXEL
YBAÑEZ VILLEGAS LUIGGI

NVO. CHIMBOTE – PERÚ


2023
CAPÍTULO 1

¿Dónde está Laravel?


En los primeros días de la web dinámica, escribir una aplicación web se veía muy
diferente de lo que es hoy. Luego, los desarrolladores fueron responsables de escribir
el código no solo para la lógica empresarial única de nuestras aplicaciones, sino
también para cada uno de los componentes que son tan comunes en todos los sitios:
autenticación de usuarios, validación de entradas, acceso a bases de datos , plantillas
y más.
Hoy en día, los programadores tienen docenas de marcos de desarrollo de
aplicaciones y miles de componentes y bibliotecas de fácil acceso. Es un
estribillo común entre los grammers profesionales que, para cuando aprendes un
marco, han aparecido tres marcos más nuevos (y supuestamente mejores) con la
intención de reemplazarlo.
" Solo porque está ahí" podría ser una justificación válida para escalar una montaña,
pero hay mejores razones para elegir usar un marco específico, o usar un marco en
absoluto. Vale la pena hacer la pregunta, ¿por qué marcos? Más específicamente, ¿por
qué Laravel?

¿Por qué usar un marco?


Es fácil ver por qué es beneficioso usar los componentes individuales, o paquetes,
que están disponibles para los desarrolladores de PHP. Con los paquetes, alguien
más es responsable de desarrollar y mantener una pieza aislada de código que tiene
un trabajo bien definido, y en teoría esa persona tiene una comprensión más profunda
de este componente único de lo que usted tiene tiempo para tener.
Frameworks como Laravel, y Symfony, Lumen y Slim, empaquetan previamente una
colección de componentes de terceros junto con un "pegamento" de marco
personalizado como archivos de configuración, proveedores de servicios, estructuras
de directorios prescritas y arranques de aplicaciones. Por lo tanto, el beneficio de
usar un marco en general es que alguien ha tomado decisiones no solo sobre
componentes individuales para usted, sino también sobre cómo esos componentes
deben encajar.
" Lo construiré yo mismo"
Supongamos que inicia una nueva aplicación web sin el beneficio de un marco. ¿Por
dónde empezar? Bueno, probablemente debería enrutar las solicitudes HTTP, por
lo que ahora debe evaluar todas las bibliotecas de solicitudes y respuestas HTTP
disponibles y elegir una. Entonces tendrás que elegir un enrutador. Ah, y
probablemente necesitarás configurar algún tipo de archivo de racionamiento de
configu‐ rutas. ¿Qué sintaxis debe usar? ¿A dónde debería ir? ¿Qué pasa con los
controladores? ¿Dónde viven y cómo se cargan? Bueno, probablemente necesite un
contenedor de inyección de dependencias para resolver los controladores y sus
dependencias. ¿Pero cuál?
Además, si no setoma el tiempo para responder a todas esas preguntas y crear con
éxito su aplicación, ¿cuál es el impacto en el próximo desarrollador? ¿Qué pasa
cuando tienes cuatro de estas aplicaciones personalizadas basadas en marcos, o una
docena, y tienes que recordar dónde viven los controladores en cada una, o cuál es la
sintaxis de enrutamiento?

Consistencia y flexibilidad
Los marcos abordan este problema proporcionando una respuesta cuidadosamente
considerada a la pregunta "¿Qué componente deberíamos usar aquí?" y asegurando
que los componentes particulares elegidos funcionenbien juntos. Además, los marcos
proporcionan convenciones que reducen la cantidad de código que un desarrollador
nuevo en el proyecto tiene que comprender: si comprende cómo funciona el
enrutamiento en un proyecto Laravel, por ejemplo, comprende cómo funciona en
todos los proyectos Laravel.
Cuando alguien prescribe implementar su propio marco para cada nuevo proyecto, lo
que realmente está defendiendo es la capacidad de incluir lo que entra y no entra en
la base de su aplicación. Eso significa que los mejores marcos no solo le
proporcionarán una base sólida, sino que también le darán la libertad de personalizar
al contenido de su corazón. Y esto, como te mostraré en el resto de este libro, es
parte de lo que hace que Lara-vel sea tan especial.

Una breve historia de los frameworks web y PHP


Una parte importante de poder responder a la pregunta "¿Por qué Laravel?" es
comprender la historia de Laravel y comprender lo que vino antes. Antes del
aumento de popularidad de Laravel, había una variedad de marcos y otros
movimientos en PHP y otros espacios de desarrollo web.

Rubí sobre raíles


David Heinemeier Hansson lanzó la primera versión de Ruby on Rails en 2004, y ha
sido difícil encontrar un marco de aplicación web desde entonces que no haya sido
influenciado por Rails de alguna manera.
Rails popularizó MVC, API JSON RESTful, convención sobre configuración,
registro activo y muchas más herramientas y convenciones que tuvieron una
profunda influencia en la forma en que los desarrolladores web abordaron sus
aplicaciones, especialmente con respecto al desarrollo rápido de aplicaciones.

La afluencia de frameworks PHP


Estaba claro para la mayoría de los desarrolladores que Rails y marcos de
aplicaciones web similares eran la ola del futuro, y los frameworks PHP, incluidos
los que ciertamente imitaban a Rails, comenzaron a aparecer rápidamente.
CakePHP fue el primero en 2005, y pronto fue seguido por Symfony, CodeIgniter,
Zend Framework y Kohana (una bifurcación de CodeIgniter). Yii llegó en 2008, y
Aura y Slim en 2010. 2011 trajo FuelPHP y Laravel, los cuales no eran exactamente
ramificaciones de CodeIgniter, sino propuestas como alternativas.
Algunos de estos marcos eran más Rails-y, centrándose en mapeadores relacionales
de objetos de base de datos (ORM), estructuras MVC y otras herramientas dirigidas
al desarrollo rápido. Otros, como Symfony y Zend, se centraron más en los patrones
de diseño empresarial y el comercio electrónico.

El Good y lo malo de CodeIgniter


CakePHP y CodeIgniter fueron los dos primeros frameworks PHP que fueron más
abiertos sobre cuánto se inspiró en Rails. CodeIgniter saltó rápidamente a la fama y
en 2010 fue posiblemente el más popular de los frameworks PHP independientes.
CodeIgniter era simple, fácil de usar y contaba con una documentación increíble y
una fuerte comunidad. Pero su uso de tecnología y patrones modernos avanzó
lentamente; y a medida que el mundo del marco creció y las herramientas de PHP
avanzaron, CodeIgniter comenzó a quedarse atrás en términos de avances
tecnológicos y características listas para usar. A diferencia de muchos otrosfr
ameworks, CodeIgniter fue administrado por una empresa, y fue lento para ponerse
al día con las características más nuevas de PHP 5.3, como los espacios de nombres
y los movimientos a Git-Hub y más tarde Composer. Fue en 2010 que Taylor
Otwell, el creador de Laravel, se sintió lo suficientemente insatisfecho con
CodeIgniter que se puso en marcha para escribir su propio marco.

Laravel 1, 2 y 3
La primera beta de Laravel 1 fue lanzada en junio de 2011, y fue escrita
completamente desde cero. Presentaba un ORM personalizado (Eloquent);
enrutamiento basado en cierres (inspirado en Ruby Sinatra); un sistema de módulos
para la extensión; y ayudantes para formularios, validación, autenticación y más.
El desarrollo inicial de Laravel se movió rápidamente, y Laravel 2 y 3 fueron
lanzados en noviembre de 2011 y febrero de 2012, respectivamente. Introdujeron
controladores, pruebas unitarias, una herramienta de línea de comandos, un
contenedor de inversión de control (IoC), relaciones elocuentes y migraciones.

Laravel 4
Con Laravel 4, Taylor reescribió todo el marco desde cero. En este punto, Composer,
el ahora omnipresente administrador de paquetes de PHP, estaba mostrando signos
de convertirse en un estándar de la industria, y Taylor vio el valor de reescribir el
marco como una colección de componentes, distribuidos y agrupados por Composer.
Taylor desarrolló un conjunto de componentes bajo el nombre en clave Illuminate y,
en mayo de 2013, lanzó Laravel 4 con una estructura completamente nueva. En
lugar de agrupar la mayor parte de su código como descarga, Laravel ahora sacó la
mayoría de sus componentes de Symfony (otro marco que lanzó sus componentes
para su uso por otros) y los componentes de Illuminate a través de Composer.
Laravel 4 también introdujo queues, un componente de correo, fachadas y siembra de
bases de datos. Y debido a que Laravel ahora confiaba en los componentes de
Symfony, se anunció que Laravel reflejaría (no exactamente, pero poco después) el
calendario de lanzamiento semestral que sigue Symfony.

Laravel 5
Laravel 4.3 estaba programado para lanzarse en noviembre de 2014, pero a medida
que el desarrollo avanzaba, quedó claro que la importancia de sus canalesmerecía un
lanzamiento importante, y Laravel 5 se lanzó en febrero de 2015.
Laravel 5 presentó una estructura de directorios renovada, la eliminación de los
ayudantes de formularios y HTML, la introducción de las interfaces de contrato, una
serie de nuevas vistas, Socialite para la autenticación de redes sociales, Elixir para la
compilación de activos, Scheduler para simplificar cron, dotenv para la gestión
simplificada del entorno, solicitudes de formularios y un nuevo RE PL (bucle de
lectura-evaluación-impresión). Desde entonces ha crecido en características y
madurez, pero no ha habido cambios importantes como en versiones anteriores.

¿ Qué tiene de especial Laravel?


Entonces, ¿qué es lo que distingue a Laravel? ¿Por qué vale la pena tener más de un
framework PHP a la vez? Todos usan componentes de Symfony de todos modos,
¿verdad? Hablemos un poco sobre lo que hace que Laravel "funcione".
La filosofía de Laravel
Solo necesita leer los materiales de marketing de Laravel y los README para
comenzar a ver sus valores. Taylor usa palabras relacionadas con la luz como
"Iluminar" y "Chispa". Y luego están estos: "Artesanos". "Elegante." También,
estos: "Soplo de aire fresco". "Nuevo comienzo". Y finalmente: "Rápido".
"Velocidad de deformación".
Los dos valores más fuertemente comunicados del marco son aumentar la velocidad
de desarrollo y la felicidad del desarrollador. Taylor ha descrito el lenguaje
"artesanal" como intencionalmente contrastante con valores más utilitarios. Puedes
ver la génesis de este tipo de pensamiento en su pregunta de 2011 en
StackExchange en la que declaró: "A veces paso cantidades ridículas de tiempo
(horas) agonizando por hacer que el código 'se vea bonito'", solo por el bien de una
mejor experiencia de mirar el código en sí. Y a menudo ha hablado sobre el valor de
hacer que sea más fácil y rápido para los desarrolladores llevar sus ideas a buen
término, eliminando barreras innecesarias para crear grandes productos.
Laravel es, en esencia, sobre equipar y capacitar a los desarrolladores. Su objetivo es
proporcionar código claro, simple y hermoso y características que ayuden a los
desarrolladores a aprender, iniciar y desarrollar rápidamente , y escribir código que
sea simple, claro y duradero.
El concepto de dirigirse a los desarrolladores es claro en todos los materiales de
Laravel. "Happy devel‐ opers make the best code" está escrito en la documentación.
"La felicidad del desarrollador desde la descarga hasta la implementación" fue el
eslogan no oficial durante un tiempo. Por supuesto, cualquier herramienta o trabajo
webdirá que quiere que los desarrolladores sean felices. Pero tener la felicidad del
desarrollador como una preocupación principal, en lugar de secundaria, ha tenido
un gran impacto en el estilo de Laravel y el progreso de la toma de decisiones.
Donde otros marcos pueden apuntar a la pureza arquitectónica como su objetivo
principal, o la compatibilidad con los objetivos y valores de los equipos de desarrollo
empresarial, el enfoque principal de Laravel es servir al desarrollador individual.
Eso no significa que no pueda escribir aplicaciones arquitectónicamente puras o listas
para la empresa en Laravel, pero no tendrá que ser a expensas de la legibilidad y la
comprensibilidad de su base de código.

Cómo Laravel logra la felicidad del desarrollador


Solo decir que quieres hacer felices a los desarrolladores es una cosa. Hacerlo es otra,
y requiere que te preguntes qué es más probable que en un marco haga infelices a los
desarrolladores y qué es más probable que los haga felices. Hay algunas maneras en
que Laravel intenta facilitar la vida de los desarrolladores .
En primer lugar, Laravel es un marco de desarrollo rápido de aplicaciones. Eso
significa que se centra en una curva de aprendizaje superficial (fácil) y en
minimizar los pasos entre iniciar una nueva aplicación y publicarla. Todas las tareas
más comunes en la creación de aplicaciones web, desde las interacciones de la base
de datos hasta la autenticación, las colas, el correo electrónico y el almacenamiento
en caché, se simplifican gracias a los componentes que proporciona Laravel. Pero
los componentes de Laravel no son solo genial por sí solos; proporcionan una API
consistente y estructuras predecibles en todo el marco. Eso significa que, cuando
estás probando algo nuevo en Laravel, lo más probable es que termines diciendo: "...
Y simplemente funciona".
Esto tampoco termina con el marco en sí. Laravel proporciona un ecosistema
completo de herramientas para crear y lanzar aplicaciones. Tiene Homestead y Valet
para el desarrollo local, Forge para la administración de servidores y Envoyer para
los desplegadoresavanzados. Y hay un conjunto de paquetes adicionales: Cajero para
pagos y suscripciones, Echo para WebSockets, Scout para búsqueda, Passport para
autenticación API, Dusk para pruebas de frontend, Socialite para inicio de sesión
social, Horizon para monitorear colas, Nova para construir paneles de administración
y Spark para arrancar su SaaS. Laravel está tratando de eliminar el trabajo
repetitivo de los trabajos de los desarrolladores para que puedan hacer algo único.
A continuación, Laravel se centra en la "convención sobre la configuración", lo que
significa que si está dispuesto a usarlos valores predeterminados de Larav el, tendrá
que hacer mucho menos trabajo que con otros marcos que requieren que declare
todas sus configuraciones, incluso si está utilizando la configuración recomendada.
Los proyectos construidos en Laravel toman menos tiempo que los construidos en la
mayoría de los otros frameworks PHP.
Laravel también se centra profundamente en la simplicidad. Es posible usar la inyección
de dependencias y la burla y el patrón y repositorios del asignador de datos y la
segregación de responsabilidad de consulta de comandos y todo tipo de otros
patrones arquitectónicos más complejos con Laravel, si lo desea. Pero mientras que
otros marcos podrían sugerir el uso de esas herramientas y estructuras en cada
proyecto, Laravel y su documentación y comunidad se inclinan hacia comenzar con
la implementación más simple posible: una función global aquí, una fachada allá,
ActiveRecord allá. Esto permite a los desarrolladores crear la aplicación más simple
posible para resolver sus necesidades, sin limitar su utilidad en entornos com ‐ plex.
Una fuente interesante de cómo Laravel es diferente de otros PHP frameworks es que
su creador y su comunidad están más conectados e inspirados por Ruby y Rails y
lenguajes de programación funcionales que por Java. Hay una fuerte corriente en el
PHP moderno para inclinarse hacia la verbosidad y la complejidad, abrazando los
aspectos más javales de PHP. Pero Laravel tiende a estar en el otro lado, adoptando
prácticas de codificación expresivas, dinámicas y simples y características del
lenguaje.

La Comunidad Laravel
Si este libro es su primera exposición a la comunidad Laravel, tiene algo especial
que esperar . Uno de los elementos distintivos de Laravel, que ha contribuido a su
crecimiento y éxito, es la comunidad acogedora y docente que lo rodea. Desde los
tutoriales en video de Laracasts de Jeffrey Way hasta Laravel News, los canales de
Slack e IRC y Discord, desde amigos de Twitter hasta bloggers, podcasts y
conferencias de Laracon, Laravel tiene una comunidad rica y vibrante llena de
personas que han estado presente desde el primer día y las personas que recién están
comenzando su propio "día uno". Y esto no es un accidente:
Desde el principio de Laravel, he tenido la idea de que todas las personas quieren
sentir que son parte de algo. Es un instinto humano natural querer pertenecer y ser
aceptado en un grupo de otras personas de ideas afines. Entonces, al inyectar
personalidad en un marco web y ser realmente activo con la comunidad, ese tipo de
sentimiento puede crecer en la comunidad.

—Taylor Otwell, entrevista de producto y soporte

Taylor entendió desde los primeros días de Laravel que un proyecto exitoso de
código abierto necesitaba dos cosas: buena documentación y una comunidad
acogedora. Y esas dos cosas son ahora sellos distintivos de Laravel.

Cómo funciona
Hasta ahora, todo lo que he compartido aquí ha sido completamente abstracto. ¿Qué
pasa con el código, preguntas? Profundicemos en una aplicación simple (Ejemplo 1-
1) para que pueda ver cómo es realmente trabajar con Laravel día a día.

Ejemplo 1-1. "Hello, World" en rutas/web.php

<? ..php

Route::get('/', function () {

regresa '¡Hola, mundo!' ;

});

La acción más simple posible que puede realizar en una aplicación Laravel es definir
una ruta y devolver un resultado cada vez que alguien visita esa ruta. Si inicializa una
nueva aplicación Laravel en su máquina, define la ruta en el Ejemplo 1-1 y luego
sirve el sitio desde el directorio público, tendrá un examen "Hello, World"
completamente funcional
Ejemplo 1-2. "Hello, World" con controladores

Archivo: rutas/web.php

<? ..php

Ruta::get('/', 'WelcomeController@index');

Archivo: app/Http/Controllers/WelcomeController.php

<? ..php

espacio de nombres App\Http\Controllers;

class WelcomeController amplía el controlador

Índice de función pública()


{

regresa '¡Hola, mundo!' ;

Y si está almacenando sus saludos en una base de datos, también se verá bastante
similar (consulte el Ejemplo 1-3).

Ejemplo 1-3. Multigreeting "Hello, World" con acceso a la base de datos

Archivo: rutas/web.php

<? ..php

use App\Greeting;

Route::get('create-greeting', function () {

$greeting = nuevo saludo;

$greeting->body = '¡Hola, mundo!' ;

$greeting->save();

});

Route::get('first-greeting', function () {

return Saludo::first()->body;
});

Archivo: app/Saludo.php

<? ..php

espacio de nombres App;

utilice Illuminate\Database\Eloquent\Model;

clase Saludo extiende Modelo

//

Archivo: base de datos/migraciones/2015_07_19_010000_create_greetings_table.php

<? ..php

use Illuminate\Database\Schema\Blueprint;

usar Illuminate\Database\Migrations\Migration;

class CreateGreetingsTable extiende la migración

función pública up()

Schema::create('greetings', function (Blueprint $table) {

$table->bigIncrements('id');

$table->string('cuerpo');

$table->timestamps();

});

función pública down()

Schema::dropIfExists('saludos');

}
}

El ejemplo 1-3 puede ser un poco abrumador, y si es así, simplemente omitirlo.


Aprenderá sobre todo lo que está sucediendo aquí en capítulos posteriores, pero ya
puede ver que con solo unas pocas líneas de código, puede configurar migrations y
modelos de base de datos y extraer registros. Es así de simple.

¿Por qué Laravel?


Entonces, ¿por qué Laravel?
Porque Laravel te ayuda a llevar tus ideas a la realidad sin desperdiciar código,
utilizando estándares de codificación modernos, rodeado de una comunidad vibrante,
con un ecosistema de herramientas empoderador.
Y porque tú, querido desarrollador, mereces ser feliz.
CAPÍTULO 2

Configuración de un entorno de desarrollo Laravel


Parte del éxito de PHP ha sido porque es difícil encontrar un servidor web que no
pueda servire PHP. Sin embargo, las herramientas modernas de PHP tienen
requisitos más estrictos que los del pasado. La mejor manera de desarrollar para
Laravel es garantizar un entorno de servidor local y remoto consistente para su
código, y afortunadamente, el ecosistema de Laravel tiene algunas herramientas
para esto.

Requisitos del sistema


Todo lo que cubriremos en este capítulo es posible con máquinas Windows, pero
necesitará docenas de páginas de instrucciones y advertencias personalizadas. Dejaré
esas instrucciones y advertencias a los usuarios reales de Windows, por lo que los
ejemplos y en el resto del libro se centrarán en los desarrolladores de Unix / Linux /
macOS.
Ya sea que elija servir su sitio web instalando PHP y otras herramientas en su
máquina local, servir su entorno de desarrollo desde una máquina virtual a través de
Vagrant o Docker, o confiar en una herramienta como MAMP / WAMP / XAMPP,
su entorno de desarrollo deberá tener todo lo siguiente instalado para servir a los
sitios de Laravel :

• PHP >= 7.1.3 para Laravel versiones 5.6 a 5.8, PHP >= 7.0.0 para la versión 5.5, PHP
>= 5.6.4 para la versión 5.4, PHP entre 5.6.4 y 7.1.* para la versión 5.3, o PHP >=
5.5.9 para las versiones 5.2 y 5.1
• Extensión OpenSSL PHP
• Extensión PDO PHP
• Extensión Mbstring PHP
• Tokenizer PHP extension
• Extensión XML PHP (Laravel 5.3 y superior)
• Extensión Ctype PHP (Laravel 5.6 y superior)
• Extensión JSON PHP (Laravel 5.6 y superior)
• Extensión BCMath PHP (Laravel 5.7 y superior)

Compositor
Cualquier máquina en la que esté desarrollando necesitará tener Composer instalado
glob‐ aliado. Si no está familiarizado con Composer, es una herramienta que está en
la base de la mayoría del desarrollo moderno de PHP. Composer es un administrador
de dependencias para PHP, al igual que NPM para Node o RubyGems para Ruby.
Pero al igual que NPM, Composer también es la base de gran parte de nuestras
pruebas, carga de scripts locales, scripts de instalación y mucho más. Necesitará
Composer para instalar Laravel, actualizar Laravel y traer departamentos externos.

Entornos de Desarrollo Local


Para muchos proyectos, será suficiente alojar su entorno de desarrollo utilizando un
conjunto de herramientas más simple. Si ya tiene MAMP o WAMP o XAMPP
instalado en nuestro sistema, es probable que esté bien ejecutar Laravel. También puede
ejecutar Laravel con el servidor web incorporado de PHP , suponiendo que su
sistema PHP sea la versión correcta.
Todo lo que realmente necesita para comenzar es la capacidad de ejecutar PHP. Todo
lo que pasa depende de ti.
Sin embargo, Laravel ofrece dos herramientas para el desarrollo local, Valet y
Homestead, y cubriremos ambas brevemente. Si no está seguro de cuál usar, le
recomendaría usarel servicio de valet y familiarizarse brevemente con Homestead;
sin embargo, ambas herramientas son valiosas y vale la pena entenderlas.

Laravel Valet
Si desea utilizar el servidor web incorporado de PHP, su opción más simple es servir
cada sitio desde una URL localhost. Si ejecuta php -S localhost:8000 -t public desde la
carpeta raíz de su sitio Laravel, el servidor web incorporado de PHP servirá a su
sitio en http://local‐ host:8000/. También puede ejecutar php artisan serve una vez que
haya configurado su aplicación para activar fácilmente un servidor equivalente.
Pero si está interesado en vincular cada uno de sus sitios a un dominio de desarrollo
específico, deberá sentirse cómodo con el archivo hosts de su sistema operativo y
usar una herramienta como dnsmasq. En su lugar, intentemos algo más simple.
Si eres un usuario de Mac (también hay bifurcaciones no oficiales para Windows y
Linux), Laravel Valet elimina la necesidad de conectar tus dominios a las carpetas de
tu aplicación. Valet instala dnsmasq y una serie de scripts PHP que permiten
escribir laravel new myapp && abrir myapp.test y que simplemente funcione. Deberá
instalar algunas herramientas con Homebrew, que la documentación lo guiará, pero
los pasos desde la instalación inicial hasta el servicio de sus aplicaciones son
pocos y simples.
Instale Valet (consulte los documentos para obtener lasúltimas instrucciones de
instalación) y apunte a uno o más directorios donde vivirán sus sitios. Dirigí el
servicio de aparcacoches desde mi ~/Sites direc‐ tory, que es donde puse todas mis
aplicaciones en desarrollo. Ahora, puede agregar .test al final del nombre del
directorio y visitarlo en su navegador.
Valet hace que sea fácil servir todas las carpetas en una carpeta determinada como
{foldername}.test usando valet park, servir una sola carpeta usando el enlace
valet, abrir el dominio servido por Valet para una carpeta usando valet open,
servir el sitio Valet con HTTPS usando valet secure y abrir un túnel ngrok para que
pueda compartir su sitio con otros con valet share.

Granja Laravel
Homestead es otra herramienta que tal vez desee utilizar para configurar su entorno
de desarrollo local. Es una herramienta de configuración que se encuentra en la parte
superior de Vagrant (que es una herramienta para administrar máquinas virtuales) y
proporciona una imagen de máquina virtual preconfigurada que estáperfectamente
configurada para el desarrollo de Laravel y refleja el entorno de producción más
común en el que se ejecutan muchos sitios de Laravel. Homestead también es
probablemente el mejor entorno de desarrollo local para desarrolladores que
ejecutan máquinas Windows.
Los documentos de Homestead son robustos y se mantienen constantemente
actualizados, por lo que solo lo referiré a ellos si desea aprender cómo funciona y
cómo configurarlo .

Vaso
No es un proyecto oficial de Laravel, pero Chris Fidao de
Servers for Hackers and Shipping Docker ha creado una
herramienta simple para crear entornos Docker para el desarrollo
de Laravel llamada Vessel. Eche un vistazo a la documentación
del buque para obtener más información.

Creación de un nuevo proyecto de Laravel


Hay dos formas de crear un nuevo proyecto Laravel, pero ambas se ejecutan desde la
línea de comunicación. La primera opción es instalar globalmente la herramienta de
instalación Laravel (usando Com‐ poser); el segundo es usar la función de creación
de proyectos de Composer.
Puede obtener información sobre ambas opciones con mayor detalle en la página de
documentación de instalación, pero le recomendaría la herramienta de instalación
Laravel.

Instalación de Laravel con Laravel Installer Tool


Si tiene Composer instalado globalmente, la instalación de la herramienta de
instalación de Laravel es tan simple como ejecutar el siguiente comando:
Composer Global requiere "Laravel/Installer"

Una vez que tenga instalada la herramienta de instalación de Laravel, poner en


marcha un nuevo proyecto de Laravel es simple. Simplemente ejecute este comando
desde su línea de comandos:
laravel new projectName

Esto creará un nuevo subdirectorio de su directorio actual llamado {projectName}


e instalar un proyecto Laravel desnudo en él.

Instalación de Laravel con la función de creación de proyectos de Composer


Composer también ofrece una función llamada create-project para crear nuevos
proyectos con un esqueleto particular. Para utilizar esta herramienta para crear un
nuevo proyecto Laravel, ejecute el siguiente comando:
composer create-project laravel/laravel projectName

Al igual que la herramienta de instalación, esto creará un subdirectorio de su


directorio actual llamado {projectName} que contiene una instalación esqueleto de
Laravel, lista para que la desarrolle.

Lambo: Super-Powered "Laravel New"


Debido a que a menudo tomo la misma serie de pasos después de crear un nuevo
proyecto de Laravel, hice un script simple llamado Lambo que automatiza esos
pasos cada vez que creo un nuevo proyecto.
Lambo ejecuta laravel new y luego confirma su código en Git, configura sus
dentiales cre‐ .env con valores predeterminados razonables, abre el proyecto en un
navegador y (opcionalmente) lo abre en su editor y toma algunos otros pasos de
compilación útiles .
Puede instalar Lambo utilizando el requisito global de Composer:
Composer Global requiere Tightenco/Lambo

Y puedes usarlo igual que laravel nuevo:


Sitios cd

lambo mi-nuevo-proyecto

Estructura del directorio de Laravel


Cuando abra un directorio que contiene una aplicación esqueleto Laravel, verá los
siguientes archivos y directorios:
app/
bootstrap/
config/
public/
resources/
routes/
storage/
tests/
vendor /

. editorconfig

.Env

. env.ejemplo

. gitattributes

. gitignore artisan
composer.jso
n composer.lock
package.json
phpunit.xml
servidor
readme.md.php
webpack.mix.js

Diferentes herramientas de compilación en Laravel antes de 5.4


En proyectos creados antes de Laravel 5.4, es probable que veas un
gulpfile.js en lugar de webpack.mix.js; esto muestra que el
proyecto está ejecutando Laravel Elixir en lugar de Laravel Mix.

Vamos a recorrerlos uno por uno para familiarizarnos.


Las carpetas
El directorio raíz contiene las siguientes carpetas de forma predeterminada:
.app
Donde irá la mayor parte de su aplicación real. . Los modelos, controladores,
comandos comunes y su código de dominio PHP entran aquí.
Bootstrap

Contiene los archivos que el marco Laravel utiliza para arrancar cada vez que se ejecuta.
config
Donde residen todos los archivos de configuración.
base de datos

Donde viven las migraciones de bases de datos, las semillas y las fábricas.
público

El directorio al que apunta el servidor cuando sirve el sitio web. Esto contiene
index.php, que es el controlador frontal que inicia el proceso de arranque y
enruta todas las solicitudes adecuadamente. También es donde van los archivos
públicos como imágenes, hojas de texto, scripts o descargas.
Recursos

Donde residen los archivos que se necesitan para otros scripts. Las vistas, los
archivos de idioma y (opcionalmente) Sass / Less / source CSS y los archivos
JavaScript de origen viven aquí.
Rutas

Donde residen todas las definiciones de ruta, tanto para rutas HTTP como
para "rutas de consola" o comandos Artisan.
almacenamiento

Donde residen las cachés, los registros y los archivos compilados del sistema.
Pruebas
Donde viven las pruebas unitarias y de integración.
vendedor

Donde Composer instala susdependencias. Se ignora en Git (marcado para ser


excluido de su sistema de control de versiones), ya que se espera que Composer
se ejecute como parte de su proceso de implementación en cualquier servidor
remoto.
Los archivos sueltos
El directorio raíz también contiene los siguientes archivos:
. editorconfig
Proporciona instrucciones a su editor de IDE/texto sobre los estándares de
codificación de Laravel (por ejemplo, el tamaño de las sangrías, el conjunto de
caracteres y si se debe recortar el espacio en blanco final). Verá esto en cualquier
aplicación de Laravel que ejecute 5.5 y versiones posteriores.
.env y . env.ejemplo

Dictar las variables de entorno (variables que se espera que sean diferentes en
cada entorno y, por lo tanto, no están comprometidas con el control de
versiones). . env.example es una plantilla que cada entorno debe duplicar para
crear su propio archivo .env, que se ignora en Git.
. gitignore y . gitattributes

Archivos de configuración de Git .


Unrtisan

Permite ejecutar comandos de Artisan (consulte el capítulo 8) desde la línea de comandos.


composer.json y composer.lock

Archivos de configuración para Composer; composer.json es editable por el


usuario y com‐ poser.lock no lo es. Estos archivos comparten información básica
sobre el proyecto y también definen sus dependencias PHP.
package.json

Como composer.json pero para activos frontend y dependencias del sistema de


compilación; instruye a NPM sobre qué dependencias basadas en JavaScript
extraer.
phpunit.xml

Un archivo de configuración para PHPUnit, la herramienta que Laravel utiliza para probar
fuera de la caja.
readme.md

Un archivo Markdown que ofrece una introducción básica a Laravel. No verá


este archivo si utiliza el instalador de Laravel.
servidor.php

Un servidor de copia de seguridad que intenta permitir que los servidores


menos capaces sigan obteniendo una vista previa de la aplicación Laravel.
webpack.mix.js

El archivo de configuración (opcional) para Mix. Si está utilizando Elixir,


verá gulpfile.js. Estos archivos son para darle instrucciones a su sistema de
compilación sobre cómo acumular y procesar sus activos de frontend.

Configuración
La configuración principal de su aplicación Laravel (configuración de conexión de
base de datos, configuración de cola y correo, etc.) se encuentra en archivos en la
carpeta de configuración . Cada uno de estos archivos devuelve una matriz PHP, y
cada valor de la matriz es accesible mediante una clave de configuración que se
compone del nombre de archivo y todas las claves descendientes, separadas por
puntos (. ).
Entonces, si crea un archivo en config/services.php se ve así :
config/services.php

<? ..php

volver [

'sparkpost' => [

'secreto' => 'abcdefg',

],

];

Puede acceder a esa variable de configuración mediante config('services.sparkpost.secret').

Cualquier variable de configuración que deba ser distinta para cada entorno (y por lo
tanto no confirmada con el control de código fuente) vivirá en sus archivos . env.
Supongamos que desea usar una clave de API de Bugsnag diferente para cada
entorno. Establecería el archivo de configuración para extraerlo de .env:
config/services.php

<? ..php

volver [

'bugsnag' => [

'api_key' => env('BUGSNAG_API_KEY'),

],

];

Esta función auxiliar env() extrae un valor del archivo .env con la misma clave. Así
que ahora, agregue esa clave a su .env (configuración para este entorno) y . Archivos
env.example (placa TEM‐ para todos los entornos):
# En .env

BUGSNAG_API_KEY=oinfp9813410942

# En . env.ejemplo

BUGSNAG_API_KEY=

Su archivo .env ya contendrá bastantes variables específicas del entorno que necesita
el marco, como qué controlador de correo utilizará y cuál es la configuración básica
de la base de datos.

Uso de env() fuera de los archivos de configuración


Ciertas características de Laravel, incluidas algunas funciones de
almacenamiento en caché y optimización, no están disponibles
si usa llamadas env() en cualquier lugar fuera de los archivos
de configuración.

La mejor manera de extraerlas variables de entorno s es configurar


elementos de configuración para cualquier cosa que desee que
sea específica del entorno. Haga que esos elementos de
configuración lean las variables de entorno y, a continuación,
haga referencia a las variables de configuración en cualquier
lugar dentro de su aplicación:
config/services.php

volver [

'bugsnag' => [

'clave' => env('BUGSNAG_API_KEY'),

],

];

En controlador, o lo que sea

$bugsnag = new Bugsnag(config('services.bugsnag.key'));


El archivo .env
Echemos un vistazo rápido al contenido predeterminado del archivo .env. Las
teclas exactas variarán dependiendo de la versión de Laravel que esté utilizando,
pero eche un vistazo al Ejemplo 2-1 para ver cómo se ven en 5.8.

Ejemplo 2-1. Las variables de entorno predeterminadas en Laravel 5.8

APP_NAME=Lara
vel
APP_ENV=APP_K
EY local=

APP_DEBUG=verdadero
APP_URL=http://localhost

LOG_CHANNEL=pila

DB_CONNECTION=
MySQL
DB_HOST=127.0.0.1
DB_PORT=3306

DB_DATABASE=granj
a
DB_USERNAME=gran
ja
DB_PASSWORD=secret
o

BROADCAST_DRIVER
=registro
CACHE_DRIVER=arch
ivo
QUEUE_CONNECTION
=sync
SESSION_DRIVER =arc
hivo
SESSION_LIFETIME=1
20

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=
null
REDIS_PORT=6379

MAIL_DRIVER=SMTP
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

AWS_ACCESS_KEY_ID
=
AWS_SECRET_ACCESS
_KEY=

PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER
=mt1

MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="$
{PUSHER_APP_CLUSTER}"

No voy a entrar en todos ellos, porque bastantes son sólo grupos de información
de autenticación para varios servicios (Pusher, Redis, DB, Mail). Sin embargo, aquí
hay dos variables ambientales importantes que debe conocer:
APP_KEY

Una cadena generada aleatoriamente que se usa para cifrar datos. Si alguna vez
está vacío, puede encontrarse con el error "No se ha especificado ninguna
clave de cifrado de aplicación". En ese caso, simplemente ejecute php artisan
key: generate y Laravel generaráuna tasa de genes para usted.

APP_DEBUG

Un valor booleano que determina si los usuarios de esta instancia de la


aplicación deben ver errores de depuración, ideal para entornos locales y de
ensayo, terrible para producción.
El resto de las configuraciones que no son de autenticación ( BROADCAST_DRIVER,
QUEUE_CONNECTION, etc.) reciben valores predeterminados que funcionan con la
menor dependencia posible de los servicios externos , lo cual es perfecto para
cuando esté comenzando.
Cuando inicie su primera aplicación Laravel, el único cambio que probablemente
querrá hacer para la mayoría de los proyectos es la configuración de la base de datos.
Utilizo Laravel Valet, así que cambio DB_DATABASE al nombre de mi proyecto,
DB_USERNAME a root, y DB_PASSWORD a una cadena vacía:
DB_DATABASE=miPro
yecto
DB_USERNAME=raíz
DB_PASSWORD=

Luego, creo una base de datos con el mismo nombre que mi proyecto en mi cliente
MySQL favorito , y estoy listo para comenzar.

Puesta en marcha
Ahora está listo y funcionando con una instalación de Laravel desnuda. Ejecute git
init, confirme los archivos desnudos con git add . y git commit, y ya estás listo para
empezar a codificar. ¡Eso es todo! Y si está utilizando Valet, puede ejecutar los
siguientes comandos y ver instantáneamente su sitio en vivo en su navegador:
laravel nuevo myProject && cd myProject && valet open
Cada vez que empiezo un nuevo proyecto, estos son los pasos que tomo:
laravel nuevo cd
myProject myProject
git init git
add .

git commit -m "Confirmación inicial"

Mantengo todos mis sitios en una carpeta ~/Sites, que he configurado como mi
principal dirección Valet, por lo que en este caso tendría instantáneamente
myProject.test accesible en mi navegador sin trabajo añadido. Puedo editar .env y
apuntarlo a una base de datos en particular, agregar esa base de datos en mi
aplicación MySQL y estoy listo para comenzar a codificar. Y recuerda, si usas
Lambo, todos estos pasos ya están tomados para ti.

Ensayo
En cada capítulo después de esto, la sección "Pruebas" al final del capítulo le
mostrará cómo escribir pruebas para la característica o características que se
cubrieron. Dado que este capítulo no cubre una característica comprobable, hablemos
de las pruebas rápidamente. (Para obtener más información sobre la escritura y
realizando pruebas en Laravel, diríjase al capítulo 12.)
Fuera de la caja, Laravel trae PHPUnit como una dependencia y está configurado
para ejecutar las pruebas en cualquier archivo en el directorio de pruebas cuyo
nombre termina con Test.php (por ejemplo, tests/UserTest.php).
Por lo tanto, lo más sencillopara escribir pruebas es crear un archivo en el directorio
de pruebas con un nombre que termine con Test.php. Y la forma más fácil de
ejecutarlos es ejecutar . /vendor/bin/ phpunit desde la línea de comandos (en la raíz
del proyecto).
Si alguna prueba requiere acceso a la base de datos, asegúrese de ejecutar sus pruebas
desde la máquina donde está alojada su base de datos, por lo que si está alojando su
base de datos en Vagrant, asegúrese de usar ssh en su caja Vagrant para ejecutar sus
pruebas desde allí. Una vez más, puedes aprender sobre esto y mucho más en el
Capítulo 12.

Además, algunas de las secciones de prueba usarán sintaxis de prueba y


características con las que aún no estará familiarizado si está leyendo el libro por
primera vez. Si el código en cualquiera de las secciones de prueba es confuso,
simplemente omita y vuelva a él después de haber tenido la oportunidad de leer el
capítulo de prueba.

TL;DR
Dado que Laravel es un framework PHP, es muy sencillo servirlo localmente. Laravel
también proporciona dos herramientas para administrar su desarrollo local: una
herramienta más simple llamada Valet que utiliza su máquina local para proporcionar
sus dependencias, y una configuración Vagran t preconfigurada llamada Homestead.
Laravel se basa y puede ser instalado por Composer y viene de la caja con una serie
de carpetas y archivos que reflejan tanto sus convenciones como su relación con
otras herramientas de código abierto.
CAPÍTULO 3

Enrutamiento y controladoress
Lafunción esencial de cualquier marco de aplicación web es tomar solicitudes de un
usuario y entregar respuestas, generalmente a través de HTTP (S). Esto significa
que definir las rutas de una aplicación es el primer y más importante proyecto a
abordar cuando se aprende un marco web; Sin rutas, tiene poca o ninguna capacidad
para interactuar con el usuario final.
En este capítulo examinaremos las rutas en Laravel; verá cómo definirlos, cómo
dirigirlos al código que deben ejecutar y cómo usar las herramientas de enrutamiento
de Laravel para manejar una amplia gama de necesidades de enrutamiento.

Una introducción rápida a MVC, los verbos HTTP y REST


La mayor parte de lo que hablaremos en este capítulo hace referencia a cómo se
estructuran las aplicaciones Model-View-Controller (MVC), y muchos de los
ejemplos que veremos usan nombres de ruta y verbos REST-ish, así que echemos
un vistazo rápido a ambos.

¿Qué es MVC ?
En MVC, tiene tres conceptos principales:
modelo

Representa una tabla de base de datos individual (o un registro de esa tabla),


piense en "Compañía" o "Perro".
vista

Representa la plantilla que envía los datos al usuario final: piense en "la
plantilla de página de inicio de sesión con este conjunto dado de HTML, CSS y
JavaScript".
controlador

Al igual que un policía de tráfico, toma solicitudes HTTP del navegador, obtiene
los datos correctos de la base de datos y otros mecanismos de almacenamiento,
valida la entrada del usuario y, eventualmente, envía una respuesta al usuario.
En la figura 3-1, puede ver que el usuario final interactuará primero con el
controlador enviando una solicitud HTTP mediante su explorador. El controlador, en
respuesta a esa solicitud, puede escribir datos y/o extraer datos delmodelo (base de
datos). Es probable que el controlador envíe datos a una vista y, a continuación, la
vista se devuelva al usuario final para que la muestre en su navegador.

Figura 3-1. Una ilustración básica de MVC

Cubriremos algunos casos de uso para Laravel que no se ajustan a esta forma
relativamente simplista de ver la arquitectura de aplicaciones, así que no se
obsesione con MVC, pero esto al menos lo preparará para abordar el resto de este
capítulo mientras hablamos de puntos de vista y controles.

Los verbos HTTP


Los verbos HTTP más comunes son GET y POST, seguidos de PUT y DELETE.
También hay HEAD, OPTIONS y PATCH, y otros dos que casi nunca se usan en el
desarrollo web normal, TRACE y CONNECT.
Aquí hay un resumen rápido:
OBTENER

Solicitar un recurso (o una lista de recursos).


CABEZA

Solicite una versión de solo encabezados de la respuesta GET.


EXPONER

Crear un recurso.
PONER
Sobrescribir un recurso.
PARCHE

Modificar un recurso.
BORRAR

Eliminar un recurso.
OPCIONES

Pregunte al servidor qué verbos están permitidos en esta URL.


La Tabla 3-1 muestra las acciones disponibles en un controlador de recursos (más
sobre esto en "Controladores de recursos" en la página 47). Cada acción espera que
llames a una URL específica pattern usando un verbo específico, para que puedas
tener una idea de para qué se usa cada verbo.

Tabla 3-1. Los métodos de los controladores de recursos de Laravel

Verbo URL Método del Nombre Descripción


controlador
OBTENER Tareas índice() tareas.índice Mostrar todas las tareas
OBTENER tareas/crear create() tareas.crear Mostrar el formulario de creación de tareas
EXPONER Tareas tienda() tasks.store Aceptar el envío de formularios desde el
formulario Crear tarea
OBTENER tareas/{tarea} mostrar() tareas.mostrar Mostrar una tarea
OBTENER Tareas/ editar() tareas.editar Editar una tarea
{tarea}/editar
PUT/ tareas/{tarea} update() tasks.update Aceptar el envío del formulario desde el formulario
PATCH de edición de tareas
BORRAR tareas/{tarea} destruir() tareas.destruir Eliminar una tarea

¿Qué es REST?
Cubriremos REST con mayor detalle en "The Basics of REST-Like JSON APIs "
en la página 337, pero como breve introducción, es un estilo arquitectónico para
crear API. Cuandohablamos de REST en este libro, haremos referencia
principalmente a algunas características, tales como:

• Estar estructurado en torno a un recurso primario a la vez (por ejemplo, tareas)


• Consiste en interacciones con estructuras de URL predecibles utilizando verbos
HTTP (como se ve en la Tabla 3-1)
• Devolver JSON y, a menudo, ser solicitado con JSON
Taquí hay más, pero generalmente "RESTful", como se usará en este libro,
significará "pat‐ terned después de estas estructuras basadas en URL para que
podamos hacer llamadas predecibles como GET /tasks/14/edit para la página de
edición". Esto es relevante (incluso cuando no se crean API) porque las estructuras
de enrutamiento de Laravel se basan en una estructura similar a REST, como se
puede ver en la Tabla 3-1.
Las API basadas en REST siguen principalmente esta misma estructura, excepto que
no tienen una ruta de creación o edición , ya que las API solo representan acciones,
no páginas que preparan las acciones.

Definiciones de ruta
En una aplicación Laravel, definirá sus rutas web en routes/web.php y sus rutas API
en routes/api.php. Las rutas web son aquellas que serán visitadaspor sus usuarios
finales; Las rutas de API son las de su API, si tiene una. Por ahora, nos centraremos
principalmente en las rutas en rutas/web.php.

Ubicación del archivo de rutas en Laravel antes de 5.3


En los proyectos que ejecutan versiones de Laravel anteriores a
5.3, solo habrá un archivo de rutas, ubicado en
app/Http/routes.php.

La forma más sencilla de definir una ruta es hacer coincidir una ruta (por ejemplo, /)
con un cierre, como se ve en el Ejemplo 3-1.

Ejemplo 3-1. Definición básica de rutas

rutas/web.php

Route::get('/', function () {

regresa '¡Hola, mundo!' ;

});

¿Qué es Uno cierre?


Los cierres son la versión PHP de las funciones anónimas. Un cierre es una función
que se puede pasar como un objeto, asignar a una variable, pasar como parámetro a
otras funciones y métodos, o incluso serializar.

Ahora ha definido que si alguien visita / (la raíz de su dominio), el enrutador de Laravel
debe ejecutar el cierre definido allí y devolver el resultado.
Una introducción rápida al middleware
Tal vez se pregunte: "¿Por qué estoy devolviendo '¡Hola, mundo!'
en lugar de repetirlo?"

Hay bastantes respuestas, pero la más simple es que hay


muchos envoltorios alrededor del ciclo de solicitud y respuesta
de Laravel, incluido algo llamado middleware. Cuando finaliza
el cierre de ruta o el método del controlador, aún no es hora de
enviar la salida al navegador; devolver el contenido permite que
continúe fluyendo a través de la pila de respuestas y el
middleware antes de que se devuelva al usuario.

Muchos sitios web simples podrían definirse completamente dentro del archivo de
rutas web. Con unas pocas rutas GET simples combinadas con algunas plantillas,
como se ilustra en el Ejemplo 3-2, puede servir un sitio web clásico fácilmente.

Ejemplo 3-2. Sitio web de ejemplo

Route::get('/', function () {
vista de retorno ('bienvenido');
});

Route::get('about', function () {
vista de retorno('acerca de');
});

Route::get('products', function () {
vista de retorno ('productos');
});

Route::get('services', function () {
vista de retorno ('servicios');
});

Llamadas estáticas
Si tiene mucha experiencia desarrollando con PHP, es posible que
se sorprenda al ver llamadas estáticas en la clase Route. Esto no es
realmente un método estático per se, sino más bien la ubicación del
servicio utilizando las fachadas de Laravel, que cubriremos en el
Capítulo 11.

Si prefiere evitar las fachadas, puede lograr estos mismos desafíos


de esta manera :

$router->get('/', function () {

regresa '¡Hola, mundo!' ;

});
Verbos de ruta
Es posible que hayas notado que hemos estado usando Route::get() en nuestras
definiciones de ruta. Esto significa que le estamos diciendo a Laravel que solo
coincida con estas rutas cuando la solicitud HTTP use la acción GET. Pero, ¿qué pasa
si es un formulario POST, o tal vez algún JavaScript que envía solicitudes PUT o
DELETE? Hay algunas otras opciones para mí para llamar a una definición de
ruta, como se ilustra en el Ejemplo 3-3.

Ejemplo 3-3. Verbos de ruta

Route::get('/', function () {

regresa '¡Hola, mundo!' ;

});

Route::post('/', function () {

Controlar a alguien que envía una solicitud POST a esta ruta

});

Route::put('/', function () {

Controlar a alguien que envía una solicitud PUT a esta ruta

});

Route::delete('/', function () {

Controlar a alguien que envía una solicitud DELETE a esta ruta

});

Route::any('/', function () {

Controlar cualquier solicitud verbal a esta ruta

});

Route::match(['get', 'post'], '/', function () {

Manejar solicitudes GET o POST a esta ruta

});
Manejo de rutas
Como probablemente hayas adivinado, pasar un cierre a la definición de ruta no es la
única forma de enseñarle cómo resolver una ruta. Los cierres son rápidos y simples,
pero cuanto más grande es su aplicación, más torpe se vuelve poner toda su lógica de
enrutamiento enun archivo. Además, las aplicaciones que usan cierres de ruta no
pueden aprovechar el almacenamiento en caché de rutas de Laravel (más sobre esto
más adelante), que puede reducir hasta cientos de milisegundos de cada solicitud.
La otra opción común es pasar un nombre y un método de controlador como una
cadena en lugar del cierre, como en el ejemplo 3-4.

Ejemplo 3-4. Rutas que llaman a métodos de controlador

Ruta::get('/', 'WelcomeController@index');

Esto le está diciendo a Laravel que pase las solicitudes a esa ruta al método index()
del controlador App\Http\Controllers\WelcomeController. A este método se le pasarán
los mismos parámetros y se tratará de la misma manera que un cierre que podría
haber colocado alternativamente en su lugar.

Sintaxis de referencia del controlador/método de Laravel

Laravel tiene una convención sobre cómo referirse a un método particular en un


controlador dado: ControllerName@methodName. A veces esto es solo una convención
de comunicación casual, pero también se usa en enlaces reales, como en Example 3-
4. Laravel analiza lo que hay antes y después de la @ y usa esos segmentos para
identificar el controlador y el método. Laravel 5.7 también introdujo la sintaxis
"tupla" (Route::get('/', [WelcomeControl ler::class, 'index'])) perotodavía es común usar
ControllerName@methodName para describir un método en la comunicación escrita .

Parámetros de ruta
Si la ruta que está definiendo tiene parámetros (segmentos en la estructura de URL
que son variables), es fácil definirlos en su ruta y pasarlos a su cierre (consulte el
Ejemplo 3-5).

Ejemplo 3-5. Parámetros de ruta

Route::get('users/{id}/friends', function ($id) {


//
});

También puede hacer que los parámetros de su ruta sean opcionales incluyendo un
signo de interrogación (? ) después del nombre del parámetro, como se ilustra en el
ejemplo 3-6. En este caso, también debe proporcionar un valor predeterminado para
la variable correspondiente de la ruta.

Ejemplo 3-6. Parámetros de ruta opcionales

Ruta::get('users/{id?}' , function ($id = 'fallbackId') {

//

});

Y puede usar expresiones regulares (regexes) para definir que una ruta solo debe
coincidir si un parámetro cumple requisitos particulares, como en el ejemplo 3-7.

Ejemplo 3-7. Restricciones de ruta de expresión regular

Route::get('users/{id}', function ($id) {

//

})->donde('id', '[0-9]+');

Route::get('users/{username}', function ($username) {

//

})->where('nombre de usuario', '[A-Za-z]+');

Route::get('posts/{id}/{slug}', function ($id, $slug) {

//

})->donde(['id' => '[0-9]+', 'slug' => '[A-Za-z]+']);

Como probablemente haya adivinado, si visita una ruta que coincide con una cadena
de ruta pero el regex no coincide con el parámetro, no se comparará. Dado que las
rutas se emparejan de arriba a abajo, los usuarios/abc omitirían el primer cierre en el
Ejemplo 3-7, pero se emparejaría con el segundo cierre, por lo que se enrutaría allí.
Por otro lado, posts/abc/123 no coincidiría con ninguno de los cierres, por lo que
devolvería un error 404 (No encontrado).

La relación de nomenclatura entre los parámetros de ruta y


los parámetros del método de cierre/controlador
Como puede ver en el Ejemplo 3-5, es más común usar los mismos nombres para los
parámetros de ruta ({id}) y los parámetros de método que inyectan en su desafío
de ruta (función ($id)). Pero, eso esto necesario?

A menos que esté usando el enlace de modelo de ruta, que se describe más
adelante en este capítulo, no. Lo único que define qué parámetro de ruta
coincide con qué parámetro de método es su orden (de izquierda un derecha), como
Nombres R oute
La forma más sencilla de hacer referencia a estas rutas en otras partes de la
aplicación es simplemente por su ruta. Hay un ayudante global url() para simplificar
ese enlace en sus vistas, si lo necesita; consulte el Ejemplo 3-8 para ver un ejemplo. El
ayudante prefijará su ruta con el dominio completo de su sitio.

Ejemplo 3-8. El ayudante url()

<a href="<? PHP echo url('/'); ?>">


Outputs <a href="http://myapp.com/">

Sin embargo, Laravel también le permite nombrar cada ruta, lo que le permite
referirse a ella sin hacer referencia explícita a la URL. Esto es útil porque significa
que puede dar apodos simples a rutas complejas, y también porque vincularlos por
nombre significa que no tiene que reescribir sus enlaces de interfaz si las rutas
cambian (consulte el Ejemplo 3-9).

Ejemplo 3-9. Definición de nombres de ruta

Definiendo una ruta con name() en routes/web.php:

Route::get('members/{id}', 'MembersController@show')->name('members.show');

Enlazar la ruta en una vista usando el ayudante route():

<a href="<? php echo route('members.show', ['id' => 14]); ?>">

Este ejemplo ilustra algunos conceptos nuevos. Primero, estamos usando la


definición de ruta fluida para agregar el nombre, encadenando el método name()
después del método get(). Este método nos permite nombrar la ruta, dándole un alias
corto para que sea más fácil de referenciar en otro lugar.

Definición de rutas personalizadas en Laravel 5.1


Las definiciones de ruta fluida no existen en Laravel 5.1. En su
lugar, deberá pasar una matriz al segundo parámetro de la
definición de su ruta; consulte los documentos de Laravel para
ver más sobre cómo funciona esto. Aquí está el ejemplo 3-9 en
Laravel 5.1:

Route::get('members/{id}',
[ 'as' => 'members.show',
'usos' => 'MembersController@show',

]);
En nuestro ejemplo, hemos llamado a esta ruta members.show; resourcePlural.
acción es una convención común dentro de Laravel para la ruta y el nombrede
vista s.

Convenciones de nomenclatura de rutas


Puede nombrar su ruta como desee, pero la convención común es usar el plural del
nombre del recurso, luego un punto, luego la acción. Entonces, aquí están las rutas
más comunes para Uno recurso llamado fotografía:
photos.index
photos.create
photos.store
fotos.mostra
r fotos.editar
photos.update
photos.destroy

Para obtener más información acerca de estas convenciones, Ver "Controladores de


recursos" en la página 47.

En este ejemplo también se introdujo el ayudante route(). Al igual que url(), está
diseñado para usarse en vistas para simplificar la vinculación a una ruta con
nombre. Si la ruta no tiene parámetros, simplemente puede pasar el nombre de la
ruta (route('members.index')) y recibir una cadena de ruta
(http://myapp.com/members). Si tiene parámetros, páselos como una matriz como el
segundo parámetro como hicimos en el Ejemplo 3-9.
En general, recomiendo usar nombres de ruta en lugar de rutass para referirse a sus
rutas y, por lo tanto, usar el ayudante route() en lugar del ayudante url(). A veces
puede ser un poco torpe, por ejemplo, si está trabajando con varios subdominios,
pero proporciona un nivel increíble de flexibilidad para cambiar posteriormente la
estructura de enrutamiento de la aplicación sin mayor penalización.
Route Grupos
A menudo, un grupo de rutas comparte una característica particular: un determinado
requisito de autenticación, un prefijo de ruta de acceso o tal vez un espacio de
nombres de controlador. Definir estas características compartidas una y otra vez en
cada ruta no solo parece tedioso, sino que también puede enturbiar la forma de su
archivo de rutas y oscurecer algunas de las estructuras de su aplicación.
Los grupos de rutas le permiten agrupar varias rutas y aplicar cualquier
configuración de configuración compartida una vez a todo el grupo, para reducir esta
duplicación. Además, los grupos de rutas son señales visuales para los futuros
desarrolladores (y para su propio cerebro) de que estas rutas están agrupadas.
Para agrupar dos o más rutas, "rodee" las definiciones de ruta con un grupo de rutas,
como se muestra en el ejemplo 3-10. En realidad , en realidad está pasando un
cierre a la definición de grupo y definiendo las rutas agrupadas dentro de ese cierre.

Ejemplo 3-10. Definición de un grupo de rutas

Route::group(function () { Route::get('hello',
function () {

devolver ' Hola';

});

Route::get('world', function () {

devolver ' Mundo';

});

});

De forma predeterminada, un grupo de rutas en realidad no hace nada. No hay


diferencia entre usar el grupo en el ejemplo 3-10 y separar un segmento de sus rutas
con comentarios de código.
Middleware
Probablemente el uso más comúnpara grupos de rutas es aplicar middleware a un
grupo de rutas. Aprenderá más sobre middleware en el Capítulo 10, pero, entre otras
cosas, son lo que Laravel usa para autenticar usuarios y restringir a los usuarios
invitados el uso de ciertas partes de un sitio.
En el ejemplo 3-11, estamos creando un grupo de rutas alrededor del panel y las
vistas de acceso y aplicando el middleware de autenticación a ambos. En este
ejemplo, esto significa que los usuarios deben iniciar sesión en la aplicación para
ver el panel o la página de la cuenta.

Ejemplo 3-11. Restringir un grupo de rutas solo a usuarios que han iniciado sesión

Route::middleware('auth')->group(function() {
Route::get('dashboard', function () {

return view('dashboard');

});

Route::get('account', function () {

return view('cuenta');

});
});

Modificación de grupos de rutas anteriores a Laravel 5.4


Al igual que la definición de ruta fluida no existía en Laravel antes
de 5.2, la aplicación fluida de modificadores como middleware,
prefijos, dominios y más a los grupos de rutas no era posible
antes de 5.4.

Aquí está el ejemplo 3-11 en Laravel 5.3 y anteriores:

Route::group(['middleware' => 'auth'], function () { Route::get('dashboard', function


() {

return view('dashboard');
});

Route::get('account', function () {

return view('cuenta');

});

});

Aplicación de middleware en controladores


A menudo es más claro y directo adjuntar middleware a sus rutas en el control ‐ler en
lugar de en la definición de la ruta. Puede hacerlo llamando al método middleware()
en el constructor del controlador. La cadena que se pasa al método middleware() es
el nombre del middleware, y opcionalmente puede encadenar métodos
modificadores (only() y except()) para definir qué métodos recibirán ese middle‐
ware:
class DashboardController amplía el controlador

función pública __construct()

$this->middleware('auth');

$this->middleware('admin-auth')

->only('editUsers');

$this->middleware('miembro del equipo')

->excepto('editUsers');

Tenga en cuenta que si está haciendo muchas personalizaciones "solo" y "excepto",


eso es a menudo una señal de que debe abrir un nuevo controlador para las rutas
excepcionales.

Limitación de velocidad
Si necesita limitar a los usuarios para que solo accedan a cualquier ruta determinada
un cierto número de veces en un período de tiempo determinado (llamado limitación
de velocidad, y más común con las API), hay un middleware listo para usar para eso
en la versión 5.2 y superior. Aplique el acelerador middleware, que toma dos
parámetros: el primero es el número de intentos permitidos a un usuario y el segundo
es el número de minutos que se deben esperar antes de restablecer el recuento de
intentos. El ejemplo 3-12 demdescribe su uso.
Ejemplo 3-12. Aplicación del middleware limitante de velocidad a una ruta

Route::middleware('auth:api', 'throttle:60,1')->group(function () { route::get('/profile', function ()


{

//

});

});

Limitación dinámica de velocidad. Si desea diferenciar el límite de velocidad de un


usuario del de otro, puede indicar al middleware del acelerador que extraiga el
recuento de intentos (su primer parámetro) del modelo Eloquent del usuario. En lugar
de pasar un recuento de intentos como el primer parámetro del acelerador, pase el
nombre de un atributo en el modelo Eloquent, y ese atributo se usará para calcular si
el usuario ha superado su límite de velocidad.
Por lo tanto, si su modelo de usuario tiene un atributo plan_rate_limit, puede usar
el dleware medio con throttle:plan_rate_limit,1.
Una breve introducción un Elocuente
Cubriremos Eloquent, el acceso a la base de datos y el generador de consultas de
Laravel en profundidad en el Capítulo 5, pero habrá algunas referencias entre ahora
y entonces que harán que una comprensión básica mar útil.

Eloquent es el mapeador relacional de objetos (ORM) de la base de datos


ActiveRecord de Laravel, que facilita la relación de una clase Post (modelo) con
la tabla de la base de datos de publicaciones y obtener todos los registros con una
llamada como Post:: all().

El generador de consultas es la herramienta que permite realizar llamadas como


Exponer::where('active', true)->get() o incluso DB::table('users')->all(). Está Crear
una consulta encadenando métodos Uno tras otro.
Prefijos de ruta
Si tiene un grupo de rutas que comparten un segmento de su ruta (por ejemplo, si el
panel de control de su sitio tiene el prefijo /dashboard), puede usar grupos de rutas
para simplificar esta estructura (consulte el Ejemplo 3-13).

Ejemplo 3-13. Prefijar un grupo de rutas

Route::prefix('dashboard')->group(function () {
Route::get('/', function () {

Controla la ruta /dashboard

});

Route::get('users', function () {

Maneja la ruta /dashboard/users

});

});

Tenga en cuenta que cada grupo con prefijo también tiene una ruta / que representa la raíz del
prefijo
: en el ejemplo 3-13 eso es /dashboard.

Rutas de reserva
En Laravel antes de 5.6, podía definir una "ruta de reserva" (que debe definir
al final del archivo de rutas) para capturar todas las rutas no coincidentes:
Route::any('{anything}', 'CatchAllController')->where('anything', '*');En Laravel 5.6+, puedes usar el
método Route::fallback() en su lugar:
Route::fallback(function () {

//

});
Enrutamiento de subdominios
El enrutamiento de subdominio es lo mismo que el prefijo de ruta, pero se define por
subdominio en lugar de prefijo de ruta. Hay dos usos principales para esto. En primer
lugar, es posible que desee presentar diferentes secciones de la aplicación (o
aplicaciones completamente diferentes) a diferentes subdominios. El ejemplo 3-14
muestra cómo puede lograr esto.

Ejemplo 3-14. Enrutamiento de subdominios

Route::domain('api.myapp.com')->group(function () {
Route::get('/', function () {

//

});

});

En segundo lugar, es posible que desee establecer parte del subdominio como
parámetro, como se ilustra en el ejemplo 3-15. Esto se hace con mayor frecuencia en
casos de multitenencia (piense en Slack o Har-vest, donde cada compcualquiera
obtiene su propio subdominio, como tighten.slack.co).

Ejemplo 3-15. Enrutamiento de subdominios parametrizado

Route::domain('{account}.myapp.com')->group(function () {
Route::get('/', function ($account) {

//

});

Route::get('users/{id}', function ($account, $id) {

//

});

});

Tenga en cuenta que cualquier parámetro para el grupo se pasa a los métodos de las
rutas agrupadas como los primeros parámetros.

Prefijos de espacio de nombres


Cuando agrupas rutas por subdominio o prefijo de ruta, es probable que sus control‐
lers tengan un espacio de nombres PHP similar. En el ejemplo del panel, todos los
controladores de las rutas del panel pueden estar bajo un espacio de nombres
Dashboard. Mediante el uso del prefijo ace de nombres de grupo de rutas, como se
muestra en el ejemplo 3-16, puede evitar referencias largas al controlador en grupos
como "Dashboard/UsersController@index" y "Dashboard/Purcha
sesController@index".
Example 3-16. Prefijos de espacio de nombres de grupo de rutas

// App\Http\Controllers\UsersController

Ruta::get('/', 'UsersController@index');

route::namespace('Dashboard')->group(function () {

App\Http\Controllers\Dashboard\PurchasesController

Ruta::get('dashboard/purchases', 'PurchasesController@index');

});

Prefijos de nombre
Los prefijos no se detienen ahí. Es común que los nombres de ruta reflejen la
cadena inherente de elementos de ruta, por lo que users/comments/5 serán atendidos
por una ruta llamada users.comments.show. En este caso, es común usar un grupo de
rutas alrededor de todas las rutas que están debajo del recurso users.comments.
Al igual que podemos prefijar segmentos de URL y espacios de nombres de
controlador, también podemos prefijar cadenas al nombre de la ruta. Con route group
name prefixes, podemos definir que cada ruta dentro de este grupo debe tener una
cadena dada con el prefijo de su nombre. En este texto, estamos anteponiendo
"usuarios". a cada nombre de ruta, luego "comentarios". (ver Ejemplo 3-17).

Ejemplo 3-17. Prefijos de nombre de grupo de rutas

Route::name('usuarios'. )->prefix('users')->group(function ()
{ Route::name('comments.' )->prefix('comments')->group(function () {

Route::get('{id}', function () {

})->name('mostrar');
});
});
Rutas firmadas
Muchas aplicaciones envían regularmente notificaciones sobre acciones únicas
(restablecer una palabra de contraseña, aceptar una invitación, etc.) y proporcionan
enlaces simples para realizar esas acciones. Imaginemos enviar un correo
electrónico confirmando que el destinatario estaba dispuesto a ser agregado a una
lista de correo.
Hay tres formas de enviar ese enlace:

1. Haga pública esa URL y espere que nadie más descubra la URL de
aprobación o modifique su propia URL de aprobación para aprobar a otra
persona.

2. Put la acción detrás de la autenticación, enlace a la acción y solicite al usuario


que inicie sesión si aún no ha iniciado sesión (lo que, en este caso, puede ser
imposible, ya que Muchos destinatarios de la lista de correo probablemente no
serán usuarios).
3. "Firme" el enlace para que demuestre de manera única que el usuario recibió
el enlace de su correo electrónico, sin que tenga que iniciar sesión; algo así
como http://myapp.com/invita‐ tions /5816/yes?signature=
030ab0ef6a8237bd86a8b8.

Una forma sencilla de lograr la última opción es usar una función introducida en Laravel.
5.6.12 llamadas URL firmadas, lo que facilita la creación de un sistema de
autenticación de firma para enviar enlaces autenticados. Estos enlaces están
compuestos por el enlace de ruta normal con una "firma" adjunta que demuestra
que la URL no se ha cambiado desde que se envió (y por lo tanto que nadie ha
modificado la URL para acceder a la URL de otra persona). información).

Controladores
He mencionado controladores varias veces, pero hasta ahora la mayoría de los
ejemplos han mostrado cierres de ruta. En el patrón MVC, los controladores son
esencialmente clases que organizan la lógica de una o más rutas juntas en un solo
lugar. Los controladores tienden a agrupar rutas similares, especialmente si su
aplicación está estructurada en un formato tradicional similar a CRUD; en este caso,
un controlador puede manejar todas las acciones que se pueden realizar en un
recurso en particular.

¿Qué es CRUD?
CRUD significa creare, leer, actualizar, eliminar, que son
las cuatro operaciones principales que las aplicaciones web
proporcionan más comúnmente en un recurso. Por ejemplo, puede
crear una nueva entrada de blog , puede leer esa publicación,
puede actualizarla o puede eliminarla.

Puede ser tentador meter toda la lógica de la aplicación en los controladores, pero es
mejor pensar en los controladores como los policías de tráfico que enrutan las
solicitudes HTTP alrededor de su aplicación. Dado que hay otras formas en que las
solicitudes pueden entrar en su aplicación
(trabajos cron, llamadas de línea de comandos de Artisan, trabajos de cola, etc.), es
aconsejable no depender de los controladores para mucho comportamiento. Esto
significa que el trabajo principal de un controlador es capturar la intención de una
solicitud HTTP y pasarla al resto de la aplicación.
Obtener la opinión del usuario
La segunda acción más común a realizar en un método de controlador es tomar
información del usuario y actuar sobre ella. Eso introduce algunos conceptos
nuevos, así que echemos un vistazo a un poco de código de muestra y veamos las
nuevas piezas.
Primero, unamos nuestra ruta; véase el ejemplo 3-25.

Ejemplo 3-25. Enlazar acciones básicas de formulario

rutas/web.php

Route::get('tasks/create', 'TasksController@create');
Route::post('tasks', 'TasksController@store');

Tenga en cuenta que estamos enlazando la acción GET de tasks/create (que muestra
un formulario para crear una nueva tarea) y la acción POST de tasks/ (que es donde
nuestro formulario PUBLICARÁ cuando estemos creando una nueva tarea ).
Podemos asumir que el método create() en nuestro controlador solo muestra un
formulario, así que veamos el método store() en el Ejemplo 3-26.

Ejemplo 3-26. Método común del controlador de entrada de formulario

TasksController.php

...

public function store()

Tarea::create(request()->only(['title', 'description']));

return redirect('tareas');

Este ejemplo hace uso de los modelos Eloquent y la funcionalidad redirect(), y


hablaremos de ellos más adelante, pero por ahora hablemos rápidamente sobre cómo
estamos obteniendo nuestros datos aquí.
Estamos usando el ayudante request() para representar la solicitud HTTP (más sobre
esto más adelante) y usando su método only() para extraer solo los campos de título
y descripción que el usuario envió.
Luego estamos pasando esos datos al método create() de nuestro modelo de tareas,
que crea una nueva instancia de la tarea con el título establecido en el título y la
descripción pasados. Se establece en la descripción aprobada. Finalmente,
redirigimos de nuevo a la página que muestra todas las tareas.
Hay algunas capas de abstracción en el trabajo aquí, quecubriremos en un segundo,
pero sepa que los datos provenientes del método only() provienen del mismo
conjunto de datos que todos los métodos comunes utilizados en el objeto Request
extraen, incluidos all() y get(). El conjunto de datos que cada uno de estos métodos
extrae presentatodos los datos proporcionados por el usuario, ya sea de parámetros de
consulta o valores POST. Entonces, nuestro usuario completó dos campos en la
página "agregar tarea": "título" y "descripción".
Para desglosar un poco la abstracción, request()->only() toma una matriz asociativa
de nombres de entrada y los devuelve:
request()->only(['título', 'descripción']);

Devuelve:

'title' => 'Cualquiera que sea el título que el usuario escribió en la página anterior', 'description'
=> 'Cualquier descripción que el usuario haya escrito en la página anterior',

Y Task::create() toma una matriz asociativa y crea una nueva tarea a partir de ella:
Tarea::create([

'title' => 'Comprar leche',

'description' => '¡Recuerda verificar la fecha de vencimiento esta vez, Norbert!' ,

]);

Al combinarlos, se crea una tarea con solo los campos "título" y "descripción"
proporcionados por el usuario.

Inserción de dependencias en controladores


Las fachadas y los ayudantes globales de Laravel presentan unainterfaz simple para
las clases más útiles en la base de código de Laravel. Puede obtener información
sobre la solicitud actual y la entrada del usuario, la sesión, las cachés y mucho más.
Pero si prefiere inyectar sus dependencias, o si desea usar un servicio que no tiene
una fachada o un ayudante, deberá encontrar alguna manera de llevar instancias de
estas clases a su controlador.
Esta es nuestra primera exposición al proveedor de servicio de Laravel. Por ahora,
si esto no te resulta familiar, puedes pensar en ello como un poco de magia Laravel;
o, si quieres saber más sobre cómo funciona realmente, puedes saltar al Capítulo 11.
Typehints en PHP
"Typehinting" en PHP significa poner el nombre de una clase o
inter‐ face delante de una variable en una firma de método:

public function __construct(Logger $logger) {}

Este typehint le dice a PHP que todo lo que se pasa al método


debe ser de tipo Logger, que podría ser una interfaz o una clase.

Como buen ejemplo, ¿qué sucede si prefiere tener una instancia del objeto Request
en lugar de usar el ayudante global? Simplemente escriba Illuminate\ Http\Request en
los parámetros del método, como en el ejemplo 3-27.

Ejemplo 3-27. Inyección del método del controlador a través de typehinting

TasksController.php

...

almacén de funciones públicas(\Illuminate\Http\Request $request)


{

Tarea::create($request->only(['title', 'description']));

return redirect('tareas');

Por lo tanto, ha definido un parámetro que debe pasarse al método store(). Y como
lo escribiste, y dado que Laravel sabe cómo resolver ese nombre de clase, tendrás el
objeto Request listo para que lo uses en tu método sin trabajo de tu parte. Sin enlace
explícito, nada más, solo está ahí como el
$request variable.

Y, como se puede ver al comparar el ejemplo 3-26 y el ejemplo 3-27, la solicitud()


helper y el objeto Request se comportan exactamente igual.
CAPÍTULO 4

Plantillas de cuchillas

En comparación con la mayoría de los otros lenguajes backend, PHP en realidad


funciona relativamente bien como un lenguaje de plantillas. Pero tiene sus defectos,
y también es feo usarlo
<? PHP en línea por todas partes, por lo que puede esperar que la mayoría de los
marcos modernos ofrezcan un lenguaje de plantillas.
Laravel ofrece un motor de plantillas personalizado llamado Blade, que está
inspirado en . Motor Razor de NET. Cuenta con una sintaxis concisa, una curva de
aprendizaje superficial, un modelo de herencia potente e intuitivo y una fácil
extensibilidad.
Para ver rápidamente cómo es la escritura de Blade, consulte el Ejemplo 4-1.

Ejemplo 4-1. Muestras de cuchillas

<h1>{{ $group->title }}</h1>


{!! $group->heroImageHtml() !! }

@forelse ($users como $user)

• {{ $user->first_name }} {{ $user->last_name }} <br>


@vacío
No hay usuarios en este grupo.
@endforelse

Como puede ver, Blade usa llaves para su "eco" e introduce una convención en la
que sus etiquetas personalizadas, llamadas "directivas", tienen el prefijo @. Usará
directivas para todas sus estructuras de control y también para la herencia y
cualquier funcionalidad personalizada que desee agregar.
La sintaxis de Blade es limpia y concisa, por lo que en su núcleo es más agradable y
ordenado trabajar con ella que con las alternativas. Pero en el momento en que
necesite cualquiercosa de cualquier complejidad en sus plantillas (herencia anidada,
condicionales complejos o recursión), Blade
comienza a brillar realmente. Al igual que los mejores componentes Laravel, toma
requisitos de aplicación complejos y los hace fáciles y accesibles.
Además, dado que toda la sintaxis de Blade se compila en código PHP normal y
luego se almacena en caché, es rápido y le permite usar PHP nativo en sus archivos
Blade si lo desea. Sin embargo , recomendaría evitar el uso de PHP si es posible;
por lo general, si necesita hacer algo que no puede hacer con Blade o una directiva
Blade personalizada, no pertenece a la plantilla.

Usando Twig con Laravel


A diferencia de muchos otros frameworks basados en Symfony ,
Laravel no usa Twig por defecto. Pero si solo estás enamorado de
Twig, hay un paquete Twig Bridge que facilita el uso de
Twig en lugar de Blade.

Eco de datos
Como puede ver en el Ejemplo 4-1, {{ y }} se usan para envolver secciones de
PHP que le gustaría repetir. {{ $variable }} es similar a <?= $variable ?> en PHP
simple.
Sin embargo, es diferente de una manera, y es posible que ya lo haya adivinado:
Blade escapa de todos los ecos de forma predeterminada utilizando htmlentities() de PHP
para proteger a sus usuarios de la inserción de scripts maliciosos. Eso significa que { {
$variable }} es funcionalmente equivalente a
<?= htmlentities($variable) ?>. Si quieres hacer eco sin el escape, usa {!!

y !!} en lugar de.

{{ y }} Cuando se utiliza Uno marco de plantillas Frontend


Es posible que haya notado que la sintaxis de eco para Hoja ({{ }}) eso Similar un
la sintaxis de eco para muchos marcos de frontend. Entonces, ¿cómo sabe Laravel
cuándo estás escribiendo Hoja versus ¿Manillar?

Blade ignorará cualquier {{ que esté precedido por una @. Por lo tanto, analizará el
primero de los siguientes ejemplos, pero el segundo se repetirá directamente:
analizado como cuchilla; el valor de $bladeVariable se repite en la vista

{{ $bladeVariable }}

@ se elimina y "{{ manillarVariable }}" se hace eco en la vista directamente

@{{ manillarVariable }}
Control Estructuras
La mayoría de las estructuras de control en Blade serán muy familiares. Muchos se
hacen eco directamente del nombre y la estructura de la misma etiqueta en PHP.
Hay algunos ayudantes de conveniencia, pero en general, las estructuras de control se
ven más limpias de lo que lo harían en PHP.

Condicionales
Primero, echemos un vistazo a las estructuras de control que permiten la lógica.

@if
¿El @if de Blade ($condition) compila para <? php if ($condition): ? >. @else, @elseif
y @endif también compilan exactamente el mismo estilo de sintaxis en PHP. Eche un
vistazo al Ejemplo 4-2 para ver algunos ejemplos.

Ejemplo 4-2. @if, @else, @elseif y @endif

@if (contar($talks) === 1)

Hay una charla en este período de tiempo. @elseif


(count($talks) === 0)

No hay conversaciones en este período de tiempo.


@else

Hay {{ count($talks) }} conversaciones en este período de tiempo.


@endif

Al igual que con los condicionales nativos de PHP, puede mezclarlos y combinarlos
como desee. No tienen ninguna lógica especial; hay literalmente un analizador que busca
algo con la forma de @if ($condition) y lo reemplaza con el código PHP apropiado.

@unless y @endunless
@unless, por otro lado, es una nueva sintaxis que no tiene un equivalente directo en
PHP. Es el inverso directo de @if. @a menos que ($condition) sea lo mismo que <?
php if (!

$condition). Puede verlo en uso en el Ejemplo 4-3.

Ejemplo 4-3. @unless y @endunless

@unless ($user->hasPaid())
Puede completar su pago cambiando a la pestaña de pago. @endunless
Bucles
A continuación, echemos un vistazo a los bucles.
@for, @foreach y @while
@for, @foreach y @while funcionan igual en Blade que en PHP; véanse los ejemplos
4-4, 4-5 y 4-6.

Ejemplo 4-4. @for y @endfor

@for ($i = 0; $i < $talk->slotsCount(); $i++) El


número es {{ $i }}<br>

@endfor

Ejemplo 4-5. @foreach y @endforeach

@foreach ($talks como $talk)

• {{ $talk->title }} ({{ $talk->length }} minutos) <br>


@endforeach

Ejemplo 4-6. @while y @endwhile

@while ($item = array_pop($items))


{{ $item->orSomething() }} <br>
@endwhile

@forelse y @endforelse
@forelse es un @foreach que también le permite programar en una reserva si el
objeto sobre el que está iterando está vacío. Lo vimos en acción al comienzo de este
capítulo; El ejemplo 4-7 muestra otro ejemplo.

Ejemplo 4-7. @forelse

@forelse ($talks como $talk)

• {{ $talk->title }} ({{ $talk->length }} minutos) <br> @vacío


No hay conversaciones este
día. @endforelse
$loop Dentro de @foreach y @forelse
Las directivas @foreach y @forelse (introducidas en Laravel 5.3) agregan una
característica que no está disponible en los bucles PHP foreach: la variable $loop.
Cuando se utiliza dentro de un bucle @foreach o @forelse, esta variable devolverá
un objeto stdClass con estos
Propiedades:
índice

El índice basado en 0 del elemento actual en el bucle; 0 significaría "primer elemento"

iteración

El índice basado en 1 del elemento actual en el bucle; 1 significaría "primer elemento"

restante

Cuántos elementos permanecen en el bucle

contar

El recuento de elementos en el bucle


Primero

Un booleano que indica si este es el primer elemento del bucle

último

Un booleano que indica si este es el último elemento del bucle


profundidad

Cuántos "niveles" de profundidad tiene este bucle : 1 para un bucle, 2 para un bucle dentro
de un bucle, etc.
padre

Una referencia a la variable $loop para el elemento de bucle primario si este bucle
está dentro de otro bucle @foreach; de lo contrario, null

Aquí hay un ejemplo de cómo usarlo :


<ul>

@foreach ($pages como $page)

<li>{{ $loop->iteration }}: {{ $page->title }}


@if ($page->hasChildren())

<ul>
@foreach ($page->children() como $child)

<li>{{ $loop->parent->iteration }}
. {{ $loop->iteración }}:
{{ $child->title }} </li>
@endforeach

</ul>
@endif

</li>
@endforeach

</ul>
Herencia de plantillas
Blade proporciona una estructura para la herencia de plantillas que permite que las
vistas se extiendan, modifiquen e incluyan otras vistas.
Echemos un vistazo a cómo se estructura la herencia con Blade.

Definición de secciones con @section/@show y @yield


Vamos ahacer una tarta con un diseño de hoja de nivel superior, como en el ejemplo
4-8. Esta es la definición de un contenedor de página genérico en el que luego
colocaremos contenido específico de la página.

Ejemplo 4-8. Diseño de la hoja

<!-- recursos/vistas/layouts/master.blade.php -->

<html>

<cabeza>

<título>Mi sitio | @yield('title', 'Home Page')</title>

</cabeza>

<cuerpo>

<div class="container">
@yield('content')

</div>

@section('footerScripts')

<script src="app.js"></script>
@show

</cuerpo>

</html>

Esto se parece un poco a una página HTML normal, pero puedes ver que hemos
cedido en dos lugares (título y contenido) y hemos definido una sección en un tercero
(footerScripts ). Tenemos tres directivas de Blade aquí: @yield ('content') solo,
@yield('title', ' Home Page') con un valor predeterminado definido y
@section/@show con contenido real.

Si bien cada uno se ve un poco diferente, los tres funcionan esencialmente igual.
Los tres están definiendo que hay una sección con un nombre dado (el primer
parámetro) que se puede extender más tarde, y los tres están definiendo qué hacer si
la sección no se extiende. Lo hacen proporcionando una reserva de cadena (' Página
de inicio'), sin reserva (que simplemente no mostrará nada si no se extiende), o una
reserva de bloque completo (en este caso,
<script src="app.js"></script>).

¿Qué es diferente? Bueno, claramente, @yield ('contenido') no tiene contenido


predeterminado. Pero además, el contenido predeterminado en @yield ('título') solo se
mostrará si nunca se exten‐ ded. Si seextiende, sus secciones secundarias no tendrán
acceso mediante programación al valor predeterminado. @section/@show, por otro
lado, está definiendo un valor predeterminado y haciéndolo de tal manera que su
contenido predeterminado estará disponible para sus hijos, a través de @parent.

Una vez que tenga un diseño principal como este, puede extenderlo en un nuevo
archivo de plantilla como en el Ejemplo 4-9.

Ejemplo 4-9. Ampliación de un diseño Blade

<!-- resources/views/dashboard.blade.php -->

@extends('layouts.master')

@section('title', 'Dashboard')

@section('contenido')

¡Bienvenido al panel de su aplicación!


@endsection

@section('footerScripts')
@parent

<script src="dashboard.js"></script>
@endsection

@show Versus @endsection


Es posible que haya notado que el Ejemplo 4-8 usa
@section/@show, pero el Ejemplo 4-9 usa @section/@endsection.
¿Cuál es la diferencia?

Utilice @show cuando defina el lugar para una sección, en la


plantilla correspondiente . Use @endsection cuando defina el
contenido de una plantilla en una plantilla secundaria.

Esta vista infantil nos permite cubrir algunos conceptos nuevos en la herencia de Blade.

@extiende
En el ejemplo 4-9, con @extends('layouts.master')), definimos que esta vista no debe
representarse por sí sola, sino que amplía otra vista. Eso significa que su papel es
definir el contenido de varias secciones, pero no permanecer en una. Es casi más
como una serie de cubos de contenido, en lugar de una página HTML. Esta línea
también define que la vista está extendiendo vidas en
resources/views/layouts/master.blade.php.
Cada archivo solo debe extender otro archivo y la llamada @extends debe ser la
primera línea del archivo.

@section y @endsection
Con @section('title', 'Dashboard'), proporcionamos nuestro contenido para la primera
sección, título. Dado que el contenido es tan corto, en lugar de usar @section y @end
sección, solo estamos usando un acceso directo. Esto nos permite pasar el contenido
como el second de @section y luego continuar. Si es un poco desconcertante de
ver
@section sin @endsection, podrías usar la sintaxis normal.

Con @section('content') y on, usamos la sintaxis normal para definir el contenido de


la sección de contenido. Solo lanzaremos un pequeño saludo por ahora. Sin embargo,
tenga en cuenta que cuando usa @section en una vista secundaria, la termina con
@endsection (o su alias @stop), en lugar de @show, que está reservada para
Definición de secciones en vistas primarias.

@padre
Finalmente, con @section('footerScripts') y activado, usamos la sintaxis normal
para definir el contenido de la sección footerScripts.
Pero recuerde, en realidad definimos ese contenido (o, al menos, su
"predeterminado") ya en el diseño maestro. Así que esta vez , tenemos dos
opciones: podemos sobrescribir el contenido desde la vista principal, o podemos
agregarle algo.
Puede ver que tenemos la opción deincluir el contenido del padre utilizando la
directiva @parent dentro de la sección. Si no lo hiciéramos, el contenido de esta
sección sobrescribiría completamente cualquier cosa definida en el padre para esta
sección.

Incluyendo ver parciales


Ahora que hemos establecido los conceptos básicos de la herencia, hay algunos
trucos más que podemos realizar.

@incluir
¿Qué pasa si estamos en una vista y queremos atraer otra vista? Tal vez tengamos un
botón de llamada a la acción "Registrarse" que queremos reutilizar en el sitio. Y tal
vez queramos personalizar el texto del botón cada vez que lo usamos . Eche un
vistazo al ejemplo 4-10.

Ejemplo 4-10. Incluyendo ver parciales con @include

<!-- resources/views/home.blade.php -->

<div class="content" data-page-name="{{ $pageName }}">

<p>He aquí por qué deberías registrarte en nuestra aplicación: <strong>It's Great. </fuerte></p>

@include('sign-up-button', ['text' => 'Mira lo genial que es'])

</div>

<!-- resources/views/sign-up-button.blade.php -->

<a class="button button--callout" data-page-name="{{ $pageName }}">

<i class="exclamation-icon"></i> {{ $text }}

</a>
@include extrae el parcial y, opcionalmente, pasa datos en él. Tenga en cuenta que no
solo puede pasar datos explícitamente a un include a través del segundo parámetro
de @include, sino que también puede hacer referencia a cualquier variable dentro del
archivo incluido que esté disponible para la vista de inclusión ( $pageName, en este
ejemplo). Una vez más, puede hacer lo que quiera, pero recomendaría que considere
siempre pasar explícitamente cada variable que pretenda usar, solo para mayor
claridad.
También se utilizan las directivas @includeIf, @includeWhen y @includeFirst, como se
muestra en el ejemplo 4-11.

Ejemplo 4-11. Incluir vistas condicionalmente

{{-- Incluir una vista si existe --}}


@includeIf('sidebars.admin', ['some' => 'data'])

{{-- Incluir una vista si una variable pasada es truth-y --}} @includeWhen($user-
>isAdmin(), 'sidebars.admin', ['some' => 'data'])

{{-- Incluir la primera vista que existe de una matriz dada de vistas --}}
@includeFirst(['customs.header', 'header'], ['some' => 'data'])

@cada uno
Probablemente pueda imaginar algunas circunstancias en las que necesitaría
recorrer una matriz o colección y @include un parcial para cada elemento. Hay una
directiva para eso: @each.
Digamos que tenemos una barra lateral compuesta de módulos, y queremos incluir
varios módulos, cada uno con un título diferente. Eche un vistazo al ejemplo 4-12.

Ejemplo 4-12. Uso de parciales de vista en un bucle con @each

<!-- resources/views/sidebar.blade.php -->

<div class="sidebar">

@each('partials.module', $modules, 'module', 'partials.empty-module')


</div>

<!-- resources/views/partials/module.blade.php -->

<div class="sidebar-module">

<h1>{{ $module->title }}</h1>

</div>
<!-- resources/views/partials/empty-module.blade.php -->

<div class="sidebar-module"> No
hay módulos :(

</div>

Considere que @each sintaxis. El primer parámetro es el nombre de la vista parcial.


El segundo es la matriz o colección sobre la que se va a iterar. El tercero es el
nombre de variable que cada elemento (en este caso, cada elemento de la matriz
$modules) se pasará a la vista como. Y el cuarto parámetro opcional es la vista para
mostrar si la matriz o colección está vacía (o, opcionalmente, puede pasar una
cadena aquí que se usará como plantilla).

Uso de pilas
Un patrón común que puede ser difícil de administrar utilizando B lade incluye
básico es cuando cada vista en una jerarquía de inclusión de Blade necesita agregar
algo a una determinada sección, casi como agregar una entrada a una matriz.
La situación más común para esto es cuando ciertas páginas (y a veces, más
ampliamente, ciertas secciones de un sitio web) tienen archivos CSS y JavaScript
únicos específicos que necesitan cargar. Imagine que tiene un archivo CSS "global"
para todo el sitio, un archivo CSS de " sección de trabajos" y un archivo CSS de
página de "solicitar un trabajo".
Las pilas de Blade están diseñadas exactamente para esta situación. En la plantilla
principal, defina una pila, que es solo un marcador de posición. Luego, en cada
plantilla secundaria puede "empujar" entradas en esa pila con @push / @endpush,
que las agrega a la parte inferior de la pila en el renderizado final. También puede
usar @prepend/@endprepend para agregarlos a la parte superior de la pila. Ejemplo
4-13 iilustra.

Ejemplo 4-13. Uso de pilas Blade

<!-- resources/views/layouts/app.blade.php -->

<html>

<cabeza><!-- la cabeza --></cabeza>


<cuerpo>

<!-- el resto de la página -->

<script src="/css/global.css"></script>

<!-- el marcador de posición donde se colocará el contenido de la pila -->

@stack('scripts')
</cuerpo>

</html>

<!-- resources/views/jobs.blade.php -->

@extends('layouts.app')

@push('scripts')

<!-- empujar algo al fondo de la pila -->


<script src="/css/jobs.css"></script>
@endpush

<!-- resources/views/jobs/apply.blade.php -->

@extends('jobs')

@prepend('scripts')

<!-- empujar algo a la parte superior de la pila -->


<script src="/css/jobs--apply.css"></script>
@endprepend

Estos generan el siguiente resultado:


<html>

<cabeza><!-- la cabeza --></cabeza>


<cuerpo>

<!-- el resto de la página -->

<script src="/css/global.css"></script>

<!-- el marcador de posición donde se colocará el contenido de la pila -->

<script src="/css/jobs--apply.css"></script>

<script src="/css/jobs.css"></script>

</cuerpo>

</html>

Uso de componentes y ranuras


Laravel ofrece otro patrón para incluir contenido entre vistas, que se introdujo en
5.4: componentes y ranuras. Los componentes tienen más sentido en contextos
cuando te encuentras usando parciales de vista y pasando grandes trozos de
contenido a ellos como variables. Eche un vistazo al Ejemplo 4-14 para ver un
ejemplo de un modelo, o popover, que podría alertar al usuario en respuesta a un
error u otra acción.

Ejemplo 4-14. Un modal como una vista incómoda parcial

<!-- resources/views/partials/modal.blade.php -->

<div class="modal">

<div>{{ $content }}</div>

<div class="botón de cierre, etc">... </div>

</div>

<!-- en otra plantilla -->

@include('partials.modal', [

'body' => '<p>La contraseña que ha proporcionado no es válida. Aquí están las reglas para
contraseñas válidas: [...] </p><p><a href="#">... </a></p>'

])

Esto es demasiado para esta variable, y es el ajuste perfecto para un componente.


Los componentes con ranuras son parciales de vista que están diseñados
explícitamente para tener grandes fragmentos ("ranuras") que están destinados a
obtener contenido de la plantilla incluida. Eche un vistazo al Ejemplo 4-15 para ver
cómo refactorizar el Ejemplo 4-14 con componentes y ranuras.

Ejemplo 4-15. Un modal como componente más apropiado con ranuras

<!-- resources/views/partials/modal.blade.php -->

<div class="modal">

<div>{{ $slot }}</div>

<div class="botón de cierre, etc">... </div>

</div>

<!-- en otra plantilla -->

@component('parcials.modal')

<p>La contraseña que ha proporcionado no es válida. Aquí


están las reglas para contraseñas válidas: [...] </p>

<p><a href="#">... </a></p> @endcomponent


Como puede ver en el Ejemplo 4-15, la directiva @component nos permite extraer
nuestro HTML de una cadena variable estrecha y volver al espacio de la plantilla. La
variable $slot en nuestra plantilla de componentes recibe cualquier contenido que se
pase en la directiva @compo nent.

Múltiples ranuras
El método que utilizamos en el Ejemplo 4-15 se denomina ranura "predeterminada";
Lo que pase entre @component y @endcomponent se pasa a la variable $slot. Pero
también puede tener algo más que la ranura predeterminada. Imaginemos un modal
con un título, como en el ejemplo 4-16.

Ejemplo 4-16. Una vista modal parcial con dos variables

<!-- resources/views/partials/modal.blade.php -->

<div class="modal">

<div class="modal-header">{{ $title }}</div>

<div>{{ $slot }}</div>

<div class="botón de cierre, etc">... </div>

</div>

Puede utilizar la directiva @slot en las llamadas @component para pasar contenido
a ranuras distintas de la predeterminada, como puede ver en el ejemplo 4-17.

Ejemplo 4-17. Pasar más de una ranura a un componente

@component('parcials.modal')
@slot('título')

Error de validación de contraseña


@endslot

<p>La contraseña que ha proporcionado no es válida. Aquí


están las reglas para contraseñas válidas: [...] </p>

<p><a href="#">... </a></p> @endcomponent


Y si tiene otras variables en su vista que no tienen sentido como ranura, aún puede
pasar una matriz de contenido como segundo parámetro para @component, al igual
que puede hacerlo con @include. Eche un vistazo al ejemplo 4-18.

Ejemplo 4-18. Pasar datos a un componente sin ranuras

@component('partials.modal', ['class' => 'danger'])

...

@endcomponent

Aliasing de un componente para que sea una directiva


Hay un truco inteligente que puede usar para hacer que sus componentes sean aún
más fáciles de llamar: alias‐ ing. Simplemente llame a Blade::component() en la
fachada Blade (la ubicación más común es el método boot() del AppServiceProvider)
y pásele primero la ubicación del componente y segundo el nombre de su directiva
deseada, como se muestra en el ejemplo 4-19.

Ejemplo 4-19. Aliasing de un componente para que sea una directiva

AppServiceProvider@boot

Blade::component('partials.modal', 'modal');

<!-- en una plantilla -->

@modal

Contenido modal aquí


@endmodal

Puede definir una plantilla principal y dejar "agujeros" en ella para el contenido
utilizando @yield y @section/@show. A continuación, puede enseñar a sus vistas
secundarias a extenderlas usando @extends('parent.view'), y definir sus secciones
usando @section/@endsection. Utilice @parent para hacer referencia al contenido
del elemento primario del bloque.
Los compositores de vistas facilitan la definición de que, cada vez que se carga una
vista o subvista en particular , debe tener cierta información disponible. Y la
inyección de servicios permite que la propia vista solicite datos directamente desde
el contenedor de la aplicación
CHAPTER 5

Bases de datos y elocuentes


Laravel proporciona un conjunto de herramientas para interactuar con las bases de
datos de su aplicación, pero la más notable es Eloquent, el ORM ActiveRecord de
Laravel (mapeador relacional de objetos).
Eloquent es una de las características más populares e influyentes de Laravel. Es un
gran ejemplo de cómo Laravel es diferente de la mayoría de los frameworks PHP;
en un mundo de ORMs Data‐ Mapper que son potentes pero complejos, Eloquent
destaca por su simplicidad. Hay una clase por tabla, que es responsable de recuperar,
representar y persitar datos en esa tabla.
Sin embargo, ya sea que elija o no usar Eloquent, aún obtendrá un montón de
beneficios de las otras herramientas de base de datos que proporciona Laravel.
Entonces, antes de profundizar en Eloquent, comenzaremos cubriendo los
conceptos básicos de la funcionalidad de la base de datos de Laravel: migraciones,
seeders y el generador de consultas.
Luego nos referiremosa Eloquent: definir sus modelos; insertar, actualizar y eliminar;
personalizar sus respuestas con descriptores de acceso, mutadores y fundición de
atributos; y finalmente las relaciones. Están sucediendo muchas cosas aquí, y es
fácil sentirse abrumado, pero si damos un paso a la vez, lo lograremos .

Configuración
Antes de entrar en cómo usar las herramientas de base de datos de Laravel ,
hagamos una pausa por un segundo y repasemos cómo configurar las credenciales
y conexiones de su base de datos.
La configuración para el acceso a la base de datos reside en config/database.php
y .env. Al igual que muchas otras áreas de configuración en Laravel, puede definir
múltiples "conexiones" y luego decidir cuál será el código que usará de forma
predeterminada.
Conexiones de base de datos
De forma predeterminada, hay una conexión para cada uno de los controladores,
como puede ver en el Ejemplo 5-1.

Ejemplo 5-1. La lista de conexiones de base de datos predeterminada

'conexiones' =>

[ 'sqlite' => [

'driver' => 'sqlite',

'database' => env('DB_DATABASE', database_path('database.sqlite')), 'prefix' =>


'',
],

'mysql' => [

'driver' => 'mysql',

'host' => env('DB_HOST', '127.0.0.1'),

'puerto' => env('DB_PORT', '3306'),

'database' => env('DB_DATABASE', 'forge'),


'username' => env('DB_USERNAME',
'forge'), 'password' =>
env('DB_PASSWORD', ''), ' unix_socket'
=> env('DB_ SOCKET', ''), 'charset' => 'utf8',

'colación' => 'utf8_unicode_ci', 'prefijo'


=> '',

'estricto' => false,


'motor' => nulo,
],

'pgsql' => [

'driver' => 'pgsql',

'host' => env('DB_HOST', '127.0.0.1'),

'puerto' => env('DB_PORT', '5432'),

'database' => env('DB_DATABASE', 'forge'),


'username' => env('DB_USERNAME',
'forge'), 'password' =>
env('DB_PASSWORD', ''), 'charset' =>
'utf8' ,
'prefijo' => '', 'esquema'
=> 'público', 'sslmode'
=> 'preferir',

],

'sqlsrv' => [

'driver' => 'sqlsrv',

'host' => env('DB_HOST', 'localhost'), 'port'


=> env('DB_PORT', '1433'),

'database' => env('DB_DATABASE', 'forge'),


'username' => env('DB_USERNAME',
'forge'), 'password' =>
env('DB_PASSWORD', ''), 'charset' =>
'utf8' ,
'prefijo' => '',

],

Nada le impide eliminar o modificar estas conexiones nombradas o crear las suyas
propias. Puede crear nuevas conexiones con nombre y podrá establecer los
controladores (MySQL, Postgres, etc.) en ellas. Entonces, si bien hay una conexión
por controlador de forma predeterminada, eso no es una restricción; podría tener
cinco conexiones diferentes, todas con el controlador mysql, si lo desea.
Cada conexión le permite definir las propiedades necesarias para conectarse y
personalizar cada tipo de conexión.
Hay algunas razones para la idea de múltiples conductores. Para empezar, la sección
"conexiones", tal como viene de la caja, es una plantilla simple que facilita el
inicio de aplicaciones que utilizan cualquiera de los tipos de conexión de base de
datos compatibles. En muchas aplicaciones, puede elegir la conexión de base de
datos que usará, completar su información e incluso eliminar las demás si lo desea.
Por lo general, los mantengo todos allí, en caso de que eventualmente pueda usarlos.
Pero también hay algunos casos en los que puede necesitar múltiples
conexionesdentro de la misma aplicación. Por ejemplo, puede usar diferentes
conexiones de base de datos para dos tipos diferentes de datos, o puede leer de uno y
escribir en otro. El soporte para múltiples conexiones lo hace posible.
Otras opcionesde configuración de bases de datos
La sección de configuración config/database.php tiene bastantes otras opciones de
configuración. Puede configurar el acceso a Redis, personalizar el nombre de la tabla
utilizada para las migraciones, determinar la conexión predeterminada y alternar si
las llamadas no elocuentes return stdClass o instancias de matriz.
Con cualquier servicio en Laravel que permita conexiones desde múltiples fuentes
(las sesiones pueden estar respaldadas por la base de datos o el almacenamiento de
archivos, la caché puede usar Redis o Memcached, las bases de datos pueden usar
MySQL o PostgreSQL), puede definir múltiples conexiones y También elija que
una conexión en particular será la "predeterminada", lo que significa que se usará
cada vez que no solicite explícitamente una conexión en particular. Así es como
solicita una conexión específica, si lo desea:
$users = DB::connection('secondary')->select('select * from users');

[role="less_space pagebreak-before"]' === Migraciones


Los marcos modernos como Laravel facilitan la definición de la estructura de su base
de datos con migraciones basadas en código. Cada nueva tabla, columna, índice y
clave se puede definir en
y cualquier entorno nuevo se pueden llevar de la base de datos vacía al esquema
perfecto de tu aplicación en segundos.

Definición de migraciones
Una migración es un único archivo que define dos cosas: las modificaciones
deseadas al ejecutar esta migración y, opcionalmente, las modificaciones deseadas
al ejecutar esta migración .

"Arriba" y "Abajo" en migraciones


Las migraciones siempre se ejecutan en orden por fecha. Cada archivo de migración
se llama algo así: 2018_10_12_000000_create_users_table.php. Cuando se migra
un nuevo sistema, el sistema toma cada migración, comenzando en la fecha más
temprana, y ejecuta su metanfetamina up() (lo está migrando) "hacia arriba" en
este punto. Pero el sistema de migración también le permite "revertir" su conjunto
más reciente de migraciones. Tomará cada uno de ellos y ejecutará su método
down(), que debería deshacer cualquier cambio que haya realizado la migración
ascendente.

El ejemplo 5-2 muestra cómo se ve la migración predeterminada de "crear tabla de


usuarios" que viene con Laravel.
Ejemplo 5-2. Migración predeterminada de "crear tabla de usuarios" de Laravel
<? ..php

use Illuminate\Database\Schema\Blueprint;

usar Illuminate\Database\Migrations\Migration;

class CreateUsersTable extiende la migración

/**

* Ejecute las migraciones.


*

* @return void
*/

función pública up()

Schema::create('users', function (Blueprint $table) {

$table->bigIncrements('id');

$table->string('nombre');

$table->string('email')->unique();

$table->timestamp('email_verified_at')->nullable();

$table->string('contraseña');

$table->rememberToken();

$table->timestamps();

});
}

/**
* Revertir las migraciones.
*
* @return void
*/
función pública down()
{
Schema::dropIfExists('users');
}

Verificación de correo electrónico


La columna email_verified_at solo está presente en
aplicaciones creadas en Laravel 5.7 y versiones posteriores.
Almacena una marca de tiempo que indica cuándo el

El usuario verificó su dirección de correo electrónico.

Como puede ver, tenemos un método up( ) y un método down(). up() le dice a la
migración que cree una nueva tabla llamada users con unos pocos campos, y down()
le dice que elimine la tabla users.

Creación de una migración


Como verá en el capítulo 8, Laravel proporciona una serie de herramientas de línea
de comandos que puede usar para interactuar con su aplicación y generar archivos
repetitivos. Uno de estos comandos le permite crear un archivo de migración. Puede
ejecutarlo usando php artisan make:migra tion, y tiene un solo parámetro, que es el
nombre de la migración. Por ejemplo, para crear la tabla que acabamos de cubrir,
ejecutaría php artisan make:migration create_users_table.
Hay dos indicadores que puede pasar opcionalmente a este comando. --create=table_name

rellena previamente la migración con código diseñado para crear una tabla denominada
table_name, y
--table=table_name solo rellena previamente la migración para modificaciones a una
tabla existente. Estos son algunos ejemplos:
php artisan make:migración create_users_table

php artisan make:migration add_votes_to_users_table --table=users


php artisan make:migration create_users_table --create=users

Creación de tablas
Ya vimos en la migración de create_users_table predeterminada que nuestras
migraciones dependen de la fachada Schema y sus métodos. Todo lo que podamos
hacer en estas migraciones dependerá de los métodos de Schema.
Para crear una nueva tabla en una migración, utilice el método create(): el primer
parámetro es el nombre de la tabla y el segundo es un cierre que define sus
columnas:
Schema::create('users', function (Blueprint $table) {

Crear columnas aquí

});

Creación de columnas
Para crear nuevas columnas en una tabla, ya sea en una llamada de creación de tabla
o en una llamada de tabla de modificación, use la instancia de Blueprint que se ha
pasado al cierre:
Schema::create('users', function (Blueprint $table) {

$table->string('nombre');

});

Echemos un vistazo a los diversos métodos disponibles en las instancias de Blueprint


para crear col‐ umns. Describiré cómo funcionan en MySQL, pero si estás usando
otra base de datos, Laravel solo usará el equivalente más cercano.
Los siguientes son los métodos Blueprint de campo simple :
integer(colName), tinyInteger(colName), smallInteger(colName),
mediumInteger(colName), bigInteger (colName)
Agrega una columna de tipo INTEGER o una de sus muchas variaciones
string(colName, length)

Añade una columna de tipo VARCHAR con una longitud opcional


binary(colName)

Agrega una columna de tipo BLOB


boolean(colName)

Añade una columna de tipo BOOLEANO (un TINYINT(1) en MySQL)


char(colName, length)

Añade una columna CHAR con una longitud opcional


datetime(colName)

Agrega una columna DATETIME

decimal(colName, precisión, escala)


Agrega una columna DECIMAL, con precisión y escala ; por ejemplo,
decimal ('cantidad', 5, 2) especifica una precisión de 5 y una escala de 2

double(colName, dígitos totales, dígitos después del decimal)

Agrega una columna DOUBLE: por ejemplo, double('tolerance', 12, 8) especifica 12


dígitos de largo, con 8 de esos dígitos a la derecha del decimal, como en
7204.05691739

enum(colName, [choiceOne, choiceTwo])

Agrega una columna ENUM, con opciones proporcionadas


float(colName, precisión, escala)

Añade una columna FLOAT (igual que double en MySQL)

json(colName) y jsonb(colName)

Agrega una columna JSON o JSONB (o una columna TEXT en Laravel 5.1)

text(colName), mediumText(colName), longText(colName)

Agrega una columna TEXTO (o sus distintos tamaños)


time(colName)

Agrega una columna TIME


marca de tiempo(colName)

Agrega una columna TIMESTAMP


uuid(colName)

Añade una columna UUID (CHAR(36) en MySQL)

Y estos son los métodos especiales (unidos) Blueprint:


increments(colName) y bigIncrements(colName)

Agregar un ID de clave principal INTEGER o BIG INTEGER incremental sin firmar

timestamps() y nullableTimestamps()

Agrega columnas de marca de tiempo created_at y updated_at


rememberToken()

Agrega una columna remember_token (VARCHAR(100)) para los tokens de usuario


"recordarme"
softDeletes()
Agrega una marca de tiempo deleted_at para su uso con eliminaciones suaves
morphs(colName)

Para un colName proporcionado, agrega un colName_id entero y una cadena


colName_type (por ejemplo, morphs(tag) agrega tag_id entero y cadena
tag_type); Para uso en relaciones Polymor‐ PHIC

Construir propiedades adicionales con fluidez


La mayoría de las propiedades de una definición de campo (su longitud, por ejemplo)
se establecen como el segundo parámetro del método de creación de campos, como
vimos en la sección anterior. Pero hay algunas otras propiedades que estableceremos
encadenando más llamadas a métodos después de la creación de la columna. Por
ejemplo, este campo de correo electrónico es anulable y se colocará (en MySQL)
justo después del campo last_name:

Schema::table('users', function (Blueprint $table) {

$table->string('email')->nullable()->after('last_name');

});

Los métodos siguientes se utilizan para establecer propiedades adicionales de un campo:


nullable()

Permite insertar valores NULL en esta columna


default('contenido predeterminado')

Especifica el contenido predeterminado de esta columna si no se proporciona ningún valor.


sin firmar()

Marca las columnas enteras como sin signo (no negativas ni positivas, sino solo un entero)
first() (sólo MySQL)

Coloca la columna primero en el orden de las columnas


after(colName) (sólo MySQL)

Coloca la columna después de otra columna en el orden de las columnas


único()

Añade un índice ÚNICO

primario()

Agrega un índice de clave principal


índice()

Agrega un índice básico


Tenga en cuenta que unique(), primary() e index() también se pueden usar fuera del
contexto de construcción de columnas fluidas, que cubriremos más adelante.

Eliminación de tablas
Si desea eliminar una tabla, hay un método dropIfExists() en Schema que toma un
parámetro, el nombre de la tabla:
Schema::dropIfExists('contacts');

Modificación de columnas
Para modificar una columna, simplemente escriba el código que escribiría para
crear la columna como si fuera nueva, y luego agregue una llamada al método
change() después de ella.

Dependencia necesaria antes de modificar columnas


Antes de modificar cualquier columna (o eliminar cualquier
columna en SQLite), deberá ejecutar composer require
doctrine/dbal.

Entonces , si tenemos una columna de cadena llamada name que tiene una longitud
de 255 y queremos cambiar su longitud a 100, así es como la escribiríamos :
Schema::table('users', function (Blueprint $table) {

$table->string('name', 100)->change();

});

Lo mismo ocurre si queremos ajustar cualquiera de sus propiedades que no estén


definidas en el nombre del método. Para hacer que un campo sea anulable, hacemos
lo siguiente:
Schema::table('contacts', function (Blueprint $table) {

$table->string('deleted_at')->nullable()->change();

});

Así es como cambiamos el nombre de una columna:


Schema::table('contacts', function (Blueprint $table)

$table->renameColumn('promoted', 'is_promoted');
});

Y así es como soltamos una columna:


Schema::table('contacts', function (Blueprint $table)

$table->dropColumn('votes');

});

Modificar varias columnas a la vez en SQLite


Si intenta eliminar o modificar varias columnas dentro de un
único cierre de migración y está utilizando SQLite, se encontrará
con errores.

En el capítulo 12, le recomiendo que use SQLite para su base


de datos de prueba, por lo que incluso si está utilizando una
base de datos más tradicional, es posible que desee considerar
esto como una limitación para fines de prueba.

Sin embargo, no es necesario crear una nueva migración para cada


uno. En su lugar, simplemente cree varias llamadas a
Schema::table() dentro del método up() de su migración:

función pública up()

Schema::table('contacts', function (Blueprint $table)

$table->dropColumn('is_promoted');

});

Schema::table('contacts', function (Blueprint $table)

$table->dropColumn('alternate_email');

});

}
Índices y claves externas
Hemos cubierto cómo crear, modificar y eliminar columnas. Pasemos a indexarlos
y relacionarlos.
Si no está familiarizado con los índices, sus bases de datos pueden sobrevivir si
nunca las usa, pero son muy importantes para la optimización del rendimiento y para
algunos controles de integridad de datos con respecto a las tablas relacionadas.
Recomendaría leer sobre ellos, pero si es absolutamente necesario, puede omitir esta
sección por ahora.

Agregar índices. Consulte el Ejemplo 5-3 para ver ejemplosde cómo agregar índices a su
columna.

Ejemplo 5-3. Agregar índices de columna en migraciones

Después de crear las columnas ...

$table->primaria('primary_id'); // Clave primaria; innecesario si se utilizan incrementos()

$table->primaria(['first_name', 'last_name']); // Teclas compuestas

$table->unique('email'); // Índice único

$table->unique('email', 'optional_custom_index_name'); // Índice único

$table->index('cantidad'); // Índice básico

$table->index('cantidad', 'optional_custom_index_name'); // Índice básico

Tenga en cuenta que el primer ejemplo, primary(), no es necesario si está utilizando


los métodos increments() o bigIncrements() para crear el índice; Esto agregará
automáticamente un índice de clave principal para usted.

Eliminación de índices. Podemos eliminar índices como se muestra en el Ejemplo 5-4.

Ejemplo 5-4. Eliminación de índices de columna en migraciones

$table->dropPrimary('contacts_id_primary');

$table->dropUnique('contacts_email_unique');

$table->dropIndex('optional_custom_index_name');

Si pasa una matriz de nombres de columna a dropIndex,

Adivina los nombres de índice para ti en función de las reglas de generación

$table->dropIndex(['email', 'amount']);
Agregar y quitar claves externas. Para agregar una clave externa que defina que una
columna determinada hace referencia a una columna de otra tabla, la sintaxis de
Laravel es simple y clara:
$table->foreign('user_id')->references('id')->on('users');

Aquí estamos agregando un índice extranjero en la columna user_id, mostrando que


hace referencia a la columna id en la tabla de usuarios. No podría ser mucho más
simple.

Si queremos especificar restricciones de clave externa, también podemos hacerlo, con


onDelete()
y onUpdate(). Por ejemplo:
$table->extranjero('user_id')

->referencias('id')

->on('usuarios')

->onDelete('cascada');

Para eliminar una clave externa, podemos eliminarla haciendo referencia a su nombre
de índice (que se genera automáticamente combinando los nombres de las columnas
y tablas que se están ref‐ erenced):
$table->dropForeign('contacts_user_id_foreign');

o pasándole una matriz de los campos a los que hace referencia en la tabla local:
$table->dropForeign(['user_id']);

Ejecución de migraciones
Una vez que haya definido sus migraciones, ¿cómo las ejecuta? Hay un comando
Artisan para eso:
php artisan migrate

Este comando ejecuta todas las migraciones "pendientes" (ejecutando el método up()
en cada una). Laravel realiza un seguimiento de las migraciones que ha ejecutado y
cuáles no. Cada vez que ejecuta este comando, comprueba si ha ejecutado todas las
migraciones disponibles y, si no lo ha hecho, ejecutará las que queden.
Hay algunas opciones en este espacio de nombrescon las que puede trabajar.
Primero, puede ejecutar sus migraciones y sus semillas (que cubriremos a
continuación):
php artisan migrate --seed

También puede ejecutar cualquiera de los siguientes comandos:


migrar:instalar

Crea la tabla de base de datos que realiza un seguimiento de los iones de


migración quetiene y no se han ejecutado; esto se ejecuta automáticamente
cuando ejecuta sus migraciones, por lo que básicamente puede ignorarlo.
migrar:restablecer

Revierte todas las migraciones de bases de datos que haya ejecutado en esta instancia.
migrar:actualizar

Revierte todas las migraciones de base de datos que ha ejecutado en esta


instancia y, a continuación, ejecuta todas las migraciones disponibles. Es lo
mismo que ejecutar migrate:reset y luego migrate, uno tras otro.

migrar:fresco

Elimina todas suscapacidades y ejecuta cada migración nuevamente. Es lo


mismo que actualizar, pero no se molesta con las migraciones "inactivas",
simplemente elimina las tablas y luego ejecuta las migraciones "hacia arriba"
nuevamente.
migrar:revertir

Revierte solo las migraciones que se ejecutaron la última vez que ejecutó
migrate o, con la opción agregada --step=n, revierte el número de migraciones
que especifique.
migrar:estado

Muestra una tabla que enumera cada migración, con una Y o N junto a cada
una que muestra si se ha ejecutado o no en este entorno.

Migración con Homestead/Vagrant


Si está ejecutando migraciones en su máquina local y su
archivo .env apunta a una base de datos en un cuadro Vagrant, sus
migraciones fallarán. Deberá ingresar a su caja Vagrant y luego
ejecutar las migraciones desde allí. Lo mismo es cierto para las
semillas y cualquier otro comando de Artisan que afecte o lea
de la base de datos.

Siembra
Sembrar con Laravel es tan simple que ha ganado una adopción generalizada como
parte de los flujos de trabajo de desarrollo nor‐ mal de una manera que no lo ha
hecho en los marcos PHP anteriores. Hay una carpeta database/seeds que viene
con una clase DatabaseSeeder, que tiene un método run() al que se llama cuando se
llama al seeder.
Hay dos formas principales de ejecutar las sembradoras: junto con una migración o
por separado. Para ejecutar un seeder junto con una migración , simplemente
agregue --seed a cualquier llamada de migración:
php artisan migrate --seed
php artisan migrate:refresh --seed

Y para ejecutarlo de forma independiente:


php artisan db:semilla

php artisan db:seed --class=VotesTableSeeder

Esto llamará al método run() de DatabaseSeeder de forma predeterminada, o a la clase


seeder especificadad por --class.

Creación de una sembradora


Para crear una sembradora, utilice el comando make:seeder Artisan:
php artisan make:seeder ContactsTableSeeder

Ahora verá aparecer una clase ContactsTableSeeder en el directorio de base de datos/semillas.


Antes de editarlo, vamos a agregarlo a la clase DatabaseSeeder, como se muestra en el
ejemplo 5-5, para que se ejecute cuando ejecutemos nuestros seeders.

Ejemplo 5-5. Llamar a un seeder personalizado desde DatabaseSeeder.php

base de datos/semillas/DatabaseSeeder.php

...

función pública run()

$this->call(ContactsTableSeeder::class);

Ahora vamos a editar la sembradora en sí. Lo más simple que podemos hacer allí es
insertar manualmente un registro usando la fachada de la base de datos, como se
ilustra en el Ejemplo 5-6.

Ejemplo 5-6. Insertar registros de base de datos en una sembradora personalizada


<? ..php

utilice Illuminate\Database\Seeder;

utilice Illuminate\Database\Eloquent\Model;

class ContactsTableSeeder extiende Seeder

función pública run()

DB::table('contacts')->insert([ 'name' =>


'Lupita Smith', 'email' => '
lupita@gmail.com',

]);

Esto nos dará un solo disco, lo cual es un buen comienzo. Pero para semillas
verdaderamente funcionales, es probable que desee hacer un bucle sobre algún tipo
de generador aleatorio y ejecutar este inserto () muchas veces, ¿verdad? Laravel tiene
una característica para eso.

Fábricas Modelo
Las fábricas de modelos definen uno (o más) patrones para crear entradas falsas para
sus tablas base de datos . De forma predeterminada, cada fábrica lleva el nombre
de una clase Eloquent , pero también puede nombrarlas después de la tabla si no
va a trabajar con Eloquent. El ejemplo 5-7 muestra la misma configuración de
fábrica en ambos sentidos.
Example 5-7. Definición de fábricas de modelos con claves de nombre de tabla y
clase Eloquent

$factory->define(User::class, function (Faker\Generator $faker) {

volver [

'nombre' => $faker->nombre,

];

});

$factory->define('users', function (Faker\Generator $faker) {

volver [
'nombre' => $faker->nombre,

];

});

Teóricamente, puedes nombrar estas fábricas como quieras, pero nombrar la fábrica
después de tu clase elocuente es el enfoque más idiomático.

Creación de una fábrica de modelos


Las fábricas modelo están ubicadas en bases de datos/fábricas. En Laravel 5.5 y
versiones posteriores, cada fábrica generalmente se define en su propia clase, con
una clave (nombre) y un cierre que definen cómo crear una nueva instancia de la
clase definida. El método $factory->define() toma el nombre de fábrica como
primer parámetro y un cierre que se ejecuta para cada generation como segundo
parámetro.

El archivo de fábrica del modelo en Laravel 5.4 y versiones anteriores


En Laravel antes de 5.5, todas las fábricas deben definirse en base
de datos/ fábricas/ModelFactory.php. No hay clases separadas para
cada fábrica hasta 5.5.

Para generar una nueva clase de fábrica, use el comando Artisan make:factory; al
igual que con la nomenclatura de las claves de fábrica , también es más común
nombrar las clases de fábrica después de los modelos Eloquent de los que están
destinadas a generar instancias de:
php artisan make:factory ContactFactory

Esto generará un nuevo archivo dentro del directorio de bases de datos/fábricas llamado
ContactFac‐ tory.php. La fábrica más simple que podríamos definir para un contacto
podría verse algo como el Ejemplo 5-8:

Ejemplo 5-8. La definición de fábrica más simple posible

$factory->define(Contact::class, function (Faker\Generator $faker) {

volver [

'name' => 'Lupita Smith', 'email' =>


' lupita@gmail.com'
];

});
Ahora podemos usar el ayudante global factory() para crear una instancia de Contact
en nuestra siembra y prueba:
Crear uno

$contact = factory(Contact::class)->create();

Crear muchos

factory(Contacto::class, 20)->create();

Sin embargo, si usáramos esa fábrica para crear 20 contactos, los 20 tendrían la
misma información. Eso es menos útil.
Obtendremos aún más beneficios de las fábricas modelo cuando aprovechemos la
instancia de Faker que ha pasado al cierre; Faker facilita la aleatorización de la
creación de datos falsos estructurados. El ejemplo anterior ahora se convierte en el
ejemplo 5-9.

Ejemplo 5-9. Una fábrica simple, modificada para usar Faker

$factory->define(Contact::class, function (Faker\Generator $faker) {

volver [

'name' => $faker->name,


'email ' => $faker->email,
];

});

Ahora, cada vez que creamos un contacto falso usando esta fábrica de modelos, todos
nuestros lazos adecuados se generarán aleatoriamente.

Garantizar la singularidad de los datos generados aleatoriamente


Si desea garantizar que los valores generados aleatoriamente de
cualquier entrada dada sean únicos en comparación con los otros
valores generados aleatoriamente durante ese proceso PHP,
puede usar el método unique() de Faker:

return ['email' => $faker->unique()->email];

Uso de una fábrica de modelos


Hay dos contextos principales en los que usaremos fábricas de modelos: pruebas, que
cubriremos en el Capítulo 12, y siembra, que cubriremos aquí. Escribamos una
sembradora usando una fábrica de mödel; eche un vistazo al ejemplo 5-10.
Ejemplo 5-10. Uso de fábricas de modelos

factory(Post::class)->create([

'title' => 'Mi mejor publicación de todas',

]);

Fábrica de nivel profesional; ¡Pero no te sientas abrumado!

factory(User::class, 20)->create()->each(function ($u) use ($post) {

$post->comments()->save(factory(Comment::class)-
>make([ 'user_id' = > $u->id,
]));

});

Para crear un objeto, usamos el ayudante global factory() y le pasamos el nombre de


la fábrica, que, como acabamos de ver, es el nombre de la clase Eloquent de la
que estamos generando una instancia. Eso devuelve la fábrica, y luego podemos
ejecutar uno de dos métodos en ella: make() o create().
Ambos métodos generan una instancia de este modelo especificado, utilizando la
definición del archivo de fábrica. La diferencia es que make() crea la instancia pero
(todavía) no la guarda en la base de datos, mientras que create() la guarda en la base
de datos al instante. Puede ver ambos en uso en los dos ejemplos del Ejemplo 5-10.
El segundo ejemplo tendrá más sentido una vez que cubramos las relaciones en
Eloquent más adelante en este capítulo.

Anulación de propiedades al llamar a una fábrica de modelos. Si pasa una matriz a make() o
create(), puede anular claves específicas de fábrica, como hicimos en el Ejemplo
5-10 para establecer el user_id en el comentario y establecer manualmente el título
de nuestra publicación.

Generar más de una instancia con una fábrica de modelos. Si pasa un número como segundo
parámetro al ayudante factory(), puede especificar que está creando más de una
instancia. En lugar de devolver una sola instancia, devolverá una colección de
instancias. Esto significa que puede tratar el resultado como una matriz, puede
asociar cada una de sus instancias con otra entidad, o puede usar otros métodos de
entidad en cada instancia, como usamos each() en el Ejemplo 5-10 para agregar un
comentario de cada nueva creación . usuario.

Fábricas de modelos de nivel profesional


Ahora que hemos cubierto los usos y arreglos más comunes de los hechos
modelo, profundicemos en algunas de las formas más complicadas en que podemos
usarlos.
Adjuntar relaciones al definir fábricas de modelos. A veces es necesario crear un
elemento relacionado junto con el elemento que está creando. Puede
utilizar un cierre en esa propiedad para crear un elemento relacionado y
extraer su ID, como se muestra en el Ejemplo 5-11.

Ejemplo 5-11. Creación de un elemento de término relacionado en una sembradora

$factory->define(Contact::class, function (Faker\Generator $faker) {

volver [

'name' => 'Lupita Smith',


'email' =>
'lupita@gmail.com'
, 'company_id' =>
function () {
return factory(App\Company::class)->create()->id;

},

];

});

A cada cierre se le pasa un único parámetro, que contiene la forma de


matriz del elemento generado hasta ese punto. Esto se puede usar de otras
maneras, como se demuestra en el Ejemplo 5-12.

Ejemplo 5-12. Uso de valores de otros parámetros en una sembradora

$factory->define(Contact::class, function (Faker\Generator $faker) {

volver [

'name' => 'Lupita Smith',


'email' =>
'lupita@gmail.com'
, 'company_id' =>
function () {

return factory(App\Company::class)->create()->id;

},

'company_size' => function ($contact) {

Utiliza la propiedad "company_id" generada anteriormente

return App\Company::find($contact['company_id'])->size;

},

];

});

Definir y acceder a varios estados de fábrica de modelos. Volvamos a


ContactFactory.php ( del Ejemplo 5-8 y del Ejemplo 5-9) por un segundo.
Disponemos de una base Contact factory definida:
$factory->define(Contact::class, function (Faker\Generator $faker) {

volver [
'name' => $faker-
>name, 'email '
=> $faker-
>email,

];

});

Pero a veces se necesita más de una fábrica para una clase de objeto. ¿Qué
pasa si necesitamos poder agregar algunos contactos que son personas muy
importantes (VIP)? Podemos usar el método state() para definir un
segundo estado de fábrica para esto, como se ve en el Ejemplo 5-13. El
primer parámetro a state() sigue siendo el nombre de la entidad que está
generando, el segundo es el nombre de su estado y el tercero es una
matriz de cualquier atributo que desee establecer específicamente para
este estado.

Ejemplo 5-13. Definición de varios estados de fábrica para el mismo modelo

$factory->define(Contact::class, function (Faker\Generator $faker) {

volver [

'name' => $faker-


>name, 'email '
=> $faker-
>email,

];

});

$factory->state(Contacto::class,
'vip', [ 'vip' => true,
]);

Si los atributos modificados requieren más que un simple valor estático,


puede pasar un seguro clo‐ en lugar de una matriz como segundo
parámetro y, a continuación, devolver una matriz de los atributos que desea
modificar, como en el ejemplo 5-14.

Ejemplo 5-14. Especificación de un estado de fábrica con un cierre

$factory->state(Contact::class, 'vip', function (Faker\Generator $faker) {

volver [

'vip' => verdadero,

'empresa' => $faker->empresa,

];

});

Ahora, hagamos una instancia de un estado específico:


$vip = factory(Contact::class, 'vip')->create();
$vips = factory(Contact::class, 'vip', 3)->create();

Estados de fábrica anteriores a Laravel 5.3


En los proyectos que ejecutan versiones de Laravel
anteriores a 5.3 , los estados de fábrica se llamaban
tipos de fábrica, y querrá usar $factory-
>defineAs() en lugar de $factory->state(). Puede
obtener más información sobre esto en los
documentos 5.2.

Vaya. Eso fue mucho. No te preocupes si eso fue


difícil de seguir, la última parte fue un poco más
alto. Volvamos a lo básico y hablemos sobre el
núcleo de las herramientas de base de datos de
Laravel: el generador de consultas.

Generador de consultas
Ahora que está conectado y ha migrado y sembrado sus tablas,
comencemos con cómo usar las herramientas de base de datos. En el núcleo
de cada pieza de la funcionalidad de la base de datos de Laravel se
encuentra el generador de consultas, una interfaz fluida para interactuar
con diferentes tipos de bases de datos con una única API clara.

¿Qué eso una interfaz fluida?


Una interfaz fluida eso aquella que utiliza principalmente el encadenamiento de
métodos para proporcionar una API más simple al usuario final. En lugar de
esperar que todos los datos relevantes se pasen un un constructor o a una llamada
de método, las cadenas de llamadas fluidas se pueden construir gradualmente, con
llamadas consecutivas. Considere esta comparación:
No fluido:

$users = .DB::escoger([«Tabla' => 'Usuarios', 'dónde' => ['tipo' => 'donante»] ]);

Fluido:

$users = .DB::mesa('usuarios')->Dónde('tipo', 'donante»)->Obtener();

La arquitectura de base de datos de Laravel puede conectarse a MySQL,


Postgres, SQLite y SQL Server a través de una sola interfaz, con solo el
cambio de algunos ajustes de configuración.
Si alguna vez ha utilizado un marco PHP, es probable que haya utilizado
una herramienta que le permite ejecutar consultas SQL "sin procesar" con
escape básico por seguridad. El generador de consultas es eso, con muchas
capas de conveniencia y ayudantes en la parte superior. Entonces,
comencemos con algunas llamadas simples.

También podría gustarte