
Compartir:
Actor de formación con una disertación sobre la comedia, llegué al desarrollo de PHP a través de la escena de las reuniones. Puedes encontrarme hablando y escribiendo sobre tecnología, o tocando/comprando discos raros de mi colección de vinilos.
Laravel 9: ¡Abróchate el cinturón!
Se ha estado trabajando en él durante un año, y el 8 de febrero, por fin salió a la venta: ¡Laravel 9 está aquí! En este artículo vamos a repasar algunas de las nuevas características, pero en lugar de una "lista de cosas", voy a proporcionar algunos comentarios y contexto adicional sobre los cambios que me han llamado la atención.
Lo más importante
No hay grandes cambios arquitectónicos ni cambios que hagan saltar las alarmas de la retrocompatibilidad (dicho esto, se trata de una versión importante y, por tanto, contiene cambios de última hora en consonancia con semver). Sin embargo, hay algunos cambios importantes fuera del código. Veámoslos:
Ciclo de liberación
Uno de los mayores cambios en Laravel recientemente fue el anuncio de Taylor Otwell de que se estaban moviendo a un ciclo de lanzamiento anual. Esto tiene sentido, ya que permite al equipo central más tiempo para comprobar las actualizaciones de dependencias dentro del ecosistema Symfony o dependencias creadas por la comunidad. Hablando de Symfony:
Correo Symfony
Symfony Mailer ha sustituido a Swift Mailer. Sobre el tema de Symfony, tuve una conversación muy interesante con la gente de SensioLabs durante PHPUK sobre el tema de las interacciones de Laravel y Symfony entre sí. Puede que a algunos desarrolladores les guste considerarse embajadores de la marca de uno u otro, y piensen que lo normal es "tomar partido", pero como se ve en el artisan cli, Symfony Mailer y otros trozos de Laravel está claro que los dos frameworks trabajan juntos mucho más de lo que la gente que intenta ser divisiva podría saber. Vale la pena recordar que ambos Fabien Potencier y Taylor Otwell ambos contribuyen con código a las organizaciones del otro, y que el ecosistema PHP en su conjunto tiene una relevancia y dirección modernas gracias a ello.
PHP8
Recuerdo haber visto a Jenny Wong de Human Made dar una charla sobre la seguridad de WordPress, y cómo el despliegue de Jetpack era una herramienta esencial para el ecosistema de WordPress, aunque con tasas de adopción muy bajas. Una de las mayores vulnerabilidades a las que se enfrenta PHP es la falta de voluntad de los desarrolladores para actualizar sus versiones de PHP. Más del 50% de la escena WordPress en ese momento estaba ejecutando software en versiones de PHP que ni siquiera eran compatibles.
Por lo tanto, es un gran impulso ver que Laravel está aumentando las versiones requeridas de PHP en línea con el ciclo de vida del núcleo de PHP. Da acceso a toda una nueva serie de características de la API, pero lo más importante es que forzar una versión mínima de PHP8 significa que se obtiene el compilador en tiempo de ejecución Just-In-Time (JIT), y por lo tanto Laravel se beneficia de un aumento significativo del rendimiento.
Con un nuevo requisito mínimo, es posible que te quedes atrapado en tu pila de servidores. Si es una molestia seria porque tienes despliegues de aplicaciones existentes, te recomendaría encarecidamente usar Laravel Shift para migrar automáticamente tus proyectos.
Flysystem
Una de las -mejores- características como desarrollador al ser introducido a Laravel fue cómo la Storage envolvía el Flysystem de Frank De Jong. La capacidad de cambiar un controlador de sistema de archivos de local a un cubo de AWS S3 cambiando los controladores:
Storage::disk('local')->put('something.jpg', 'Images'); Storage::disk('s3')->put('something.jpg', 'Images');
Flysystem 3.0.0 fue lanzado el 14 de enero e incluye mejoras de versión en línea con el requisito mínimo de Laravel para PHP8 (para Flysystem 8.0.2 específicamente) y mejoras de la API en torno a la navegación de directorios, tales como FilesystemReader::directoryExists('Storage\Images')
Laravel 9 ahora utiliza Flysystem 3.
Las cosas pequeñas
Se trata de pequeños retoques y añadidos que, sin embargo, suman un gran paquete de nuevas funciones.
Agrupación de controladores de ruta
Admito que soy muy particular cuando se trata de organizar rutas en aplicaciones web. Creo que esto viene de la experiencia de ver archivos de rutas masivas con más de mil entradas con poca estructura a la forma en que se ordenan. La forma en que me gusta abordar el enrutamiento es el uso de estructuras de directorios para los controladores individuales, cargados en el proveedor de servicios de rutas.
Ya codifico rutas como grupos con nombre, pero la diferencia aquí es que el cierre te permitirá vincular un grupo a un controlador específico. Esto no hará una diferencia si usted toma el enfoque de los controladores invocables (un montón más de archivos, pero potencialmente más flojo acoplamiento), pero si usted tiene algo así como una API REST que hace operaciones CRUD estándar, por ejemplo - esto se ve muy bien en el código. Tomemos por ejemplo este controlador:
Class ReportController extends Controller
{
public function index(){}
public function store(){}
public function delete(){}
public function show(){}
}Ahora, con la agrupación de controladores puede envolver los métodos del controlador en el archivo de rutas:
Route::controller(ReportController::class)->group(function () {
Route::get('/reports', 'index');
Route::post('/reports', 'store');
Route::delete('/reports/{id}', 'delete');
Route::get('/reports/{id}', 'show')
}
Lista de rutas Salida CLI
Hablando de rutas, la salida de routes:list se ha cambiado, a una vista mucho más amigable para el desarrollador:

Fijaciones de alcance forzado
Se trata de un pequeño cambio que vincula las relaciones de modelo con la vinculación de rutas de una forma mucho más clara. Anteriormente, se podía conseguir una vinculación de ámbito forzada añadiendo una clave personalizada dentro de un registro hijo:
Route::get('/users/{user}/reports/{report:id}', function (User $user, Report $report) {
return $report;
})Sin utilizar esa clave personalizada, no se aplicaría ninguna relación de modelo, lo que significa que siempre que el usuario y el informe sean claves válidas, devolverá esa entidad de ejemplo aunque no tenga ninguna relación (por ejemplo, una entidad de ejemplo). $report aunque no tuviera ninguna relación (p. ej. Model::hasOne(User::class))
Ahora tenemos un método que permite esta lógica de forma mucho más explícita:
Route::get('/users/{user}/reports/{report}', function (User $user, Report $report) {
return $report;
})->scopeBindings();
Enums
PHP8.1 incluye la nueva clase enums que puede ser tratada como un objeto con valores de retorno llamados estáticamente o puede ser una "enumeración respaldada" que contiene un valor. Vi a Derek Rethans introducir esta característica en el escenario en PHPUK 2022y debo decir, desde nuestra perspectiva en Vonage, que podría resultar extremadamente útil. Como nos ocupamos de las llamadas de voz y mensajería, muchas de estas características implementadas en el SDK DE PHP tienen propiedades estáticas para definir y recuperar el estado (por ejemplo, el estado de este SMS es "0"). Los Enums tienen el potencial de tener un tipo asociado, en lugar de una extensa lista de propiedades estáticas.
Con la introducción de Enums, un par de características de Laravel 9 se han escrito para tomar ventaja de esto.
Enumeraciones de reparto de atributos
He trabajado en un proyecto en el que esto habría ahorrado muchos dolores de cabeza. Todo en una base de datos MySQL bastante grande se extendía a partir de una clase base/tabla de base "Evento", con las entidades extendidas restringidas por enums MySQL. Suena bien, ¿verdad? Cuando ampliamos la plataforma, había que añadir un nuevo enum, lo que provocaba un reindexado en una tabla con varios cientos de millones de registros. Siempre se caía.
Considere cómo escribiría una migración para una columna de tabla enum:
$table->enum('eventType', ['SpotifyEvent', 'VideoEvent', 'AppleEvent'])
OK, así que cada vez que se añade un nuevo enum, hay que hacer una nueva migración, además de tener que actualizar el Modelo.
En Laravel 9, puedes especificar una clase enum en su lugar, manteniendo la lógica en tu código backend en lugar de tu base de datos. Si bien es una desventaja desde el punto de vista de la base de datos con un almacenamiento ineficiente, hace que el código sea más legible. Por lo tanto, su migración sería una columna varchar en su lugar:
$table->string('eventType')->default('SpotifyEvent');
Y su lógica se sentaría dentro de una clase enum respaldada que es referenciada dentro del Modelo $casts array:
enum EventType: string {
case SpotifyEvent = 'spotify';
case VideoEvent = 'video';
case AppleEvent = 'apple';
}
class EventEntry extends Model
{
protected $casts = [
'eventType' => EventType::class
];
}
Así que eso une nuestro casting hacia y desde la base de datos: puedes probarlo con tinker:
php artisan tinker
\App\Model\EventEntry::first()->eventType->value;
Y su valor de cadena volverá. eventType devolverá en realidad un objeto enum, así que por eso necesitamos añadir el atributo value para obtener la propiedad respaldada.
Vinculación de rutas con Enums
También puede utilizar clases enum dentro de la vinculación de rutas. Digamos que desea restringir la siguiente ruta:
Route::get('events/eventType');Ahora puedes enlazar la clase enum, así:
Route::get('/events/{eventType}', function (EventType $eventType) {
return $eventType->value;
});
Cobertura de las pruebas
Volver a Xdebug para usarlo en mi cadena de herramientas de desarrollo diario fue una especie de revelación después de años de usar die() y dd() depuración. Cuando empecé a trabajar en nuestro SDK de PHP, vi que nuestro CI utiliza CodeCov para asegurar que los Pull Requests no puedan ser fusionados sin suficiente cobertura dentro del conjunto de pruebas. La cobertura viene por cortesía de Xdebug, por lo que necesita habilitar la cobertura en su archivo .ini en primer lugar:
xdebug.mode=develop,debug,coverage
Ahora, si ejecuta artisan test --coverageobtendrá un informe con la cobertura de su aplicación:

Muy bonito, ¿eh?
¿Y ahora qué?
Esta versión marca otro hito en el viaje de Laravel, pero lo que es realmente asombroso es el ecosistema extendido construido a su alrededor - Vapor, Breeze, Octane, Sail, Horizon... la lista continúa. Lo que me parece emocionante de la creciente lista de proyectos Laravel es su inclusión en la Fundación PHPcreada a raíz de la retirada de la retirada de Nikita Popov del desarrollo del núcleo de PHP. Junto con Symfony, está bastante claro que la línea inmortal "PHP está muerto"no podría estar más lejos de la realidad.
Compartir:
Actor de formación con una disertación sobre la comedia, llegué al desarrollo de PHP a través de la escena de las reuniones. Puedes encontrarme hablando y escribiendo sobre tecnología, o tocando/comprando discos raros de mi colección de vinilos.