Mejores prácticas, consejos y trucos de Laravel para 2025


Estamos a punto de entrar en 2025, y Laravel sigue siendo la elección preferida para el desarrollo web, ofreciendo a los desarrolladores herramientas para crear aplicaciones potentes y eficientes. Este artículo presenta algunas prácticas clave, consejos y trucos que, ya seas un principiante o un desarrollador experimentado, te ayudarán a mejorar la calidad del código, simplificar tu flujo de trabajo y entregar mejores aplicaciones. Estas ideas te ayudarán a aprovechar al máximo Laravel y a mejorar tus habilidades de desarrollo.

Mantén Laravel y tus paquetes actualizados

Mantener Laravel actualizado tiene varios beneficios clave:

  • Mejora de la seguridad: Las actualizaciones regulares incluyen importantes correcciones de seguridad que protegen tu aplicación.
  • Mejor rendimiento: Las actualizaciones suelen mejorar el rendimiento, lo que resulta en tiempos de carga más rápidos y un código más eficiente.
  • Nuevas funciones: Mantenerse al día te permite disfrutar de nuevas características que mejoran la experiencia de desarrollo.
  • Compatibilidad: Asegura una mejor compatibilidad con los últimos paquetes oficiales y de la comunidad.

Mantener tus paquetes actualizados: Ejecutar composer update regularmente es crucial. Esta simple práctica es una de las mejores maneras de asegurarte de que tus paquetes estén actualizados con las últimas funciones y parches de seguridad.

Si temes actualizar, podría significar que tus pruebas no son suficientes.

Al adoptar prácticas de prueba, puedes asegurarte de que las actualizaciones importantes no rompan tu código, aprovechando así las mejoras de Laravel.

Si no quieres actualizar manualmente, puedes probar la herramienta de gestión de entornos ServBay, que ya incluye versiones beta de PHP 8.4. Con ServBay, puedes mantener más fácilmente Laravel y diversos paquetes actualizados.

Mantén buenas pruebas en tu proyecto para prevenir errores críticos

Las pruebas automatizadas son un área amplia pero a menudo subestimada. Sin embargo, son una de las mejores prácticas para garantizar la confiabilidad del proyecto.

Los beneficios clave de mantener un sólido conjunto de pruebas son:

  • Menos errores: Las pruebas regulares ayudan a detectar problemas temprano, lo que resulta en un código más estable.
  • Clientes más satisfechos: Un software confiable genera usuarios satisfechos que pueden confiar en tu producto.
  • Empleadores más satisfechos: Un proyecto bien probado refleja profesionalismo y compromiso con la calidad.
  • Desarrolladores seguros: Con un conjunto de pruebas completo, puedes realizar cambios sin preocuparte por introducir nuevos errores. Volver al proyecto después de un descanso ya no resulta desalentador.

Al modificar el código, simplemente ejecuta php artisan test para identificar cualquier funcionalidad dañada, soluciona los problemas y repite este proceso.

Las pruebas automatizadas pueden aumentar significativamente la estabilidad del proyecto, lo que a su vez puede impulsar tu carrera.

Para ayudarte a comenzar, Laracasts ofrece cursos gratuitos sobre pruebas. Puedes aprender PHPUnit (el estándar de la industria) y Pest (un marco de pruebas moderno que simplifica las pruebas en PHP). Se recomienda encarecidamente comenzar con el curso "Pest From Scratch".

Sigue la organización de directorios por defecto

¿Te has preguntado por qué usar un framework como Laravel?

Los frameworks proporcionan un enfoque estructurado para el desarrollo, asegurando que todos los miembros del equipo se mantengan alineados y trabajen hacia un objetivo común. Incluyen una rica funcionalidad compleja y probada en la práctica, permitiéndote concentrarte en los aspectos únicos de tu proyecto sin distraerte con los detalles.

Entonces, ¿se considera una buena práctica seguir la estructura de proyecto por defecto de Laravel? ¡Por supuesto! Las razones son las siguientes:

  • Conveniencia: Las convenciones y la estructura de Laravel están bien documentadas. Cuando vuelvas al proyecto después de unas semanas o meses, apreciarás la claridad y familiaridad de la configuración por defecto.
  • Colaboración en equipo: Al trabajar con otros miembros del equipo, todos comprenden las convenciones de Laravel, lo que facilita la colaboración. Aprovechar este conocimiento compartido puede impulsar el proyecto hacia adelante, en lugar de reinventar la rueda en cada giro.

Usa solicitudes de formulario personalizadas para manejar validaciones complejas

Las solicitudes de formulario personalizadas en Laravel son herramientas poderosas para manejar la validación, proporcionando varias ventajas clave:

  • Reutilización de la lógica de validación: Puedes reutilizar fácilmente las reglas de validación en múltiples controladores, manteniendo tu código DRY (Don't Repeat Yourself).
  • Reducción de la sobrecarga en los controladores: Al descargar el código de validación a clases de solicitud de formulario dedicadas, mantienes los controladores claros y enfocados en la lógica de negocio.

Creando una solicitud de formulario personalizada

Crear una solicitud de formulario personalizada es simple. Solo necesitas ejecutar el siguiente comando de Artisan:

php artisan make:request StorePostRequest

Luego, en tu controlador, puedes simplemente tipar la solicitud:

use App\Http\Requests\StorePostRequest;

class PostController
{
    public function store(StorePostRequest $request)
    {
        $validated = $request->validated();
        Post::create($validated);
        // Otras lógicas...
    }
}

Mejorando la solicitud de formulario personalizada

Las solicitudes de formulario personalizadas también pueden incluir lógica adicional más allá de la validación. Por ejemplo, puedes normalizar los datos de entrada antes de que lleguen al controlador sobrescribiendo el método prepareForValidation:

public function prepareForValidation()
{
    $this->merge([
        'slug' => Str::slug($this->title),
    ]);
}

En este ejemplo, el método genera automáticamente un slug a partir del título antes de que ocurra la validación.

Gestión de autorizaciones

Las solicitudes de formulario personalizadas también pueden manejar la lógica de autorización. Si encuentras que usar políticas es demasiado engorroso, puedes incluir chequeos de autorización simples directamente en la solicitud de formulario.

Usa controladores de acción única para simplificar tu código

Incluso siguiendo las mejores prácticas, los controladores pueden volverse pesados. Una buena solución es usar controladores de acción única en Laravel. Estos controladores están diseñados para manejar una sola acción, en lugar de manejar múltiples acciones como los controladores de recursos estándar.

Creando un controlador de acción única

Para crear un controlador de acción única, utiliza el siguiente comando de Artisan:

php artisan make:controller ShowPostController --invokable

Este comando creará un controlador que solo tiene una acción, llamada __invoke. Para más información sobre el método mágico __invoke, consulta la documentación de Laravel.

Definiendo rutas

Con un controlador de acción única, puedes simplificar la definición de rutas. Aquí te mostramos cómo usarlo en las rutas:

use App\Http\Controllers\ShowPostController;

// Ruta de controlador de acción única
Route::get('/posts/{post}', ShowPostController::class);

Mejores prácticas subjetivas

El uso de controladores de acción única es una práctica subjetiva. Dependerá de ti y de tu equipo decidir si este enfoque se adapta a la estructura y preferencias de legibilidad del proyecto.

Usa middleware para evitar la duplicación de código

En Laravel, el middleware es una herramienta poderosa que te permite filtrar o modificar las solicitudes entrantes. Al aprovechar el middleware, puedes evitar la duplicación de código y mantener tus controladores claros y manejables. Aquí tienes algunos escenarios comunes de uso de middleware:

  • Verificar permisos requeridos: Asegurarte de que los usuarios tengan los permisos necesarios para acceder a ciertas rutas.
  • Configurar la zona horaria del usuario: Comprobar el idioma preferido del usuario y ajustar la zona del aplicativo en consecuencia.

Laravel ofrece varios middleware integrados para tareas comunes, como autenticación y limitación de velocidad.

Creando middleware personalizado

Para crear middleware personalizado, utiliza el siguiente comando de Artisan:

php artisan make:middleware CheckTokens

En tu middleware, puedes definir la lógica para manejar la solicitud. Aquí tienes un ejemplo de un middleware que verifica si el usuario tiene suficientes tokens:

public function handle(Request $request, Closure $next): Response
{
    if (! $request->user()->hasEnoughTokens()) {
        abort(403); // Prohibir acceso
    }
    return $next($request); // Continuar al siguiente middleware o controlador de solicitud
}

Adjuntando middleware a rutas

Una vez que hayas definido el middleware, puedes adjuntarlo a tantas rutas como desees. Este enfoque modular ayuda a mantener el código claro y a reducir la duplicación en los controladores.

Route::middleware('check.tokens')->group(function () {
    Route::get('/protected-resource', [ResourceController::class, 'index']);
    Route::post('/protected-action', [ResourceController::class, 'store']);
});

Usa políticas para implementar autorización

En Laravel, utilizar políticas para la autorización es crucial para construir aplicaciones claras y mantenibles. Tres beneficios principales de usar políticas son:

  • Compartir la lógica de autorización entre múltiples controladores: Al integrar las reglas de autorización en políticas, se fomenta la consistencia y se elimina la duplicación de código en la aplicación.
  • Reducir la complejidad de los controladores: Mover la lógica de autorización a las políticas permite que los controladores se concentren en su tarea principal, generando un código más claro y fácil de entender.
  • Simplificar el acceso al código de autorización: Al colocar las políticas en el directorio app/Policies, los desarrolladores pueden encontrar y modificar fácilmente las reglas de autorización cuando sea necesario.

Veamos un escenario práctico de actualización de publicaciones usando políticas:

// app/Policies/PostPolicy.php
public function update(User $user, Post $post)
{
    return $user->id === $post->user_id; // Verificar si el usuario es el propietario de la publicación
}

// app/Http/Controllers/PostController.php
public function update(Request $request, Post $post)
{
    $this->authorize('update', $post); // Verificar si la operación de actualización está autorizada

    // Si está autorizado, continuar con el proceso de actualización
    // ...
}

Asegúrate de que las migraciones estén actualizadas

Las migraciones son una forma de definir la estructura de la base de datos mediante código PHP puro. Puedes considerarlas como una alternativa basada en código a phpMyAdmin, proporcionando un método programático para gestionar la estructura de la base de datos. Este enfoque es especialmente beneficioso para equipos, ya que permite que todos reproduzcan el mismo entorno de desarrollo en sus máquinas locales y mantengan un historial claro de los cambios en Git.

Las migraciones también facilitan el despliegue del proyecto en nuevos entornos (como staging o producción) sin necesidad de exportar la base de datos desde otros entornos. Sin embargo, una trampa común es que algunos desarrolladores realizan cambios directamente en la base de datos en lugar de crear nuevas migraciones. Esta práctica puede causar inconvenientes a otros miembros del equipo, quienes pueden necesitar solicitar un volcado de la base de datos por Slack. Para mejorar el proyecto y mantener la consistencia, es importante aprovechar eficazmente las migraciones.

Aprovecha las migraciones anónimas para evitar conflictos (Laravel 8 y superiores)

Las migraciones anónimas son una solución efectiva para evitar conflictos de nombres de clase. Con esta función, puedes crear múltiples migraciones llamadas "update_posts_table" sin encontrar errores, lo que ayuda a reducir la fricción durante el proceso de desarrollo.

En Laravel 9 y versiones superiores, cuando ejecutas el siguiente comando, se generan automáticamente migraciones anónimas:

php artisan make:migration UpdatePostsTable

La estructura de estas migraciones es la siguiente:

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

return new class extends Migration {
    // Lógica de migración aquí
};

Curiosamente, también puedes implementar migraciones anónimas en Laravel 8. Para hacerlo, simplemente reemplaza el nombre de la clase con return new class y asegúrate de incluir un punto y coma al final. Así, incluso en versiones anteriores, podrás disfrutar de los beneficios de las migraciones anónimas.

Implementa correctamente el método down() para revertir cambios

El método down() es utilizado por el comando php artisan migrate:rollback para deshacer los cambios realizados en la base de datos. Cuando algunos desarrolladores optan por implementarlo y otros no, es importante asegurarse de que, si lo usas, tu método down() esté correctamente definido.

En esencia, el método down() debe revertir las operaciones realizadas en el método up(). Aquí tienes un ejemplo básico:

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

return new class extends Migration {
    public function up()
    {
        Schema::table('posts', function (Blueprint $table) {
            // Cambiar la columna de booleano a fecha y hora.
            $table->datetime('is_published')->nullable()->change();
        });
    }

    public function down()
    {
        Schema::table('posts', function (Blueprint $table) {
            // Restaurar la columna a su estado original durante la reversión.
            $table->boolean('is_published')->default(false)->change();
        });
    }
};

Si no deseas usar el método down(), simplemente puedes eliminarlo.

Sigue las pautas de nomenclatura de tablas de Eloquent

Seguir las convenciones de nomenclatura de tablas de Laravel es una práctica sencilla que puede beneficiar enormemente a tu equipo. Cuando usas comandos de Artisan, el framework maneja automáticamente estas convenciones, como php artisan make:model Post --migration --factory.

Si por alguna razón no puedes usar estos comandos, aquí tienes una guía rápida:

  • Para un modelo llamado Post, la tabla correspondiente debería llamarse posts, en plural. Por ejemplo:

    • Modelo Comment → tabla comments
    • Modelo Reply → tabla replies
  • Para una tabla intermedia que conecta Post y Comment (por ejemplo, comment_post):

    • Usa la forma singular de ambos nombres.
    • Ordena alfabéticamente.

Para más detalles, consulta la documentación oficial.

Evita el problema N+1 usando la carga anticipada

¡Hay más mejores prácticas que presentar! ¿Te has encontrado con el problema N+1? La carga anticipada es una forma efectiva de prevenirlos.

Por ejemplo, si estás mostrando una lista de 30 publicaciones y sus autores, debido a la carga perezosa, Eloquent ejecutará una consulta para las 30 publicaciones y luego ejecutará 30 consultas adicionales para cada autor (lo que significa que cada vez que llames a $post->user en el código, se recuperará la relación del usuario).

La solución es simple: usa el método with() para reducir el número de consultas de 31 a 2.

Post::with('author')->get();

Para evitar el problema N+1, puedes configurar la aplicación para que arroje una excepción si alguna relación se carga de forma perezosa. Esta restricción solo debe aplicarse en el entorno local.

Model::preventLazyLoading(
    // Devuelve `true` a menos que sea un entorno de producción.
    ! app()->isProduction()
);

Usa el modo estricto de Eloquent para evitar problemas de rendimiento y errores

El modo estricto de Eloquent es una herramienta valiosa para la depuración. Ayuda a los desarrolladores a identificar problemas potenciales durante el desarrollo al arrojar excepciones en varias situaciones:

  • Cargas perezosas de relaciones: La carga perezosa puede causar problemas de rendimiento, especialmente al manejar conjuntos de datos grandes. Esto ocurre cuando solo se obtienen modelos relacionados desde la base de datos al acceder a ellos. En modo estricto, si una relación se carga de forma perezosa, se lanzará una excepción, fomentando el uso de la carga anticipada.
  • Asignación de atributos no rellenables: La propiedad $fillable en los modelos Eloquent previene vulnerabilidades de asignación masiva. Si intentas asignar un atributo no rellenable, se lanzará una excepción, asegurando que los desarrolladores mantengan precaución al manejar la asignación masiva.
  • Acceso a atributos inexistentes: Intentar acceder a atributos que no existen o que no se han recuperado de la base de datos puede resultar en comportamientos o errores impredecibles. El modo estricto lanzará excepciones en tales casos, ayudando a los desarrolladores a localizar y resolver estos problemas.

Para habilitar el modo estricto, agrega el siguiente código al método boot() de AppServiceProvider.php:

Model::shouldBeStrict(
    // Solo se habilitará fuera del entorno de producción.
    ! app()->isProduction()
);

Usa el nuevo método para definir accesores y mutadores

Laravel 9 introdujo una nueva forma de declarar accesores y mutadores. Aquí está cómo deberías implementarlos ahora:

use Illuminate\Database\Eloquent\Casts\Attribute;

class Pokemon
{
    public function name(): Attribute
    {
        $locale = app()->getLocale();
        return Attribute::make(
            get: fn($value) => $value[$locale],
            set: fn($value) => [$locale => $value],
        );
    }
}

Esta nueva sintaxis te permite definir accesores y mutadores de manera más concisa. También puedes almacenar en caché valores que son costosos de calcular:

use Illuminate\Database\Eloquent\Casts\Attribute;

public function someAttribute(): Attribute
{
    return Attribute::make(
        fn() => /* Realiza alguna operación. */
    )->shouldCache();
}

En comparación, el método anterior se veía así:

class Pokemon
{
    public function getNameAttribute(): string
    {
        $locale = app()->getLocale();
        return $this->attributes['name'][$locale];
    }

    public function setNameAttribute($value): string
    {
        $locale = app()->getLocale();
        return $this->attributes['name'][$locale] = $value;
    }
}

Cambiar a la nueva sintaxis simplifica el código y mejora la legibilidad.

Usa dispatchAfterResponse() para manejar tareas de larga duración

Al manejar tareas que consumen tiempo (como enviar un correo electrónico después de enviar un formulario de contacto), puedes mejorar la experiencia del usuario retrasando la tarea hasta que el servidor responda al usuario. Aquí es donde entra en juego dispatchAfterResponse(), que permite posponer procesos de larga duración:

SendContactEmail::dispatchAfterResponse($input);

O, si prefieres usar una

Además de utilizar solicitudes de formulario personalizadas, puedes implementar la validación directamente en el modelo. Esto es útil cuando necesitas asegurarte de que los datos siempre sean válidos, independientemente de cómo se creen o actualicen. Puedes hacerlo utilizando el método boot() en tu modelo:

use Illuminate\Database\Eloquent\Model;
use Illuminate\Validation\ValidationException;

class Post extends Model
{
    protected static function boot()
    {
        parent::boot();

        static::creating(function ($post) {
            $validator = Validator::make($post->attributesToArray(), [
                'title' => 'required|string|max:255',
                'content' => 'required|string',
            ]);

            if ($validator->fails()) {
                throw new ValidationException($validator);
            }
        });
    }
}

Usa Jobs para Procesos en Segundo Plano

Cuando tienes tareas que pueden llevar tiempo (como el procesamiento de imágenes o la generación de informes), es recomendable usar Jobs para ejecutarlas en segundo plano. Esto mejora la experiencia del usuario al no hacerles esperar mientras se completan estas tareas.

Puedes crear un Job usando el siguiente comando:

php artisan make:job ProcessImage

Luego, dentro del Job, implementa la lógica que necesitas:

class ProcessImage implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, SerializesModels;

    protected $imagePath;

    public function __construct($imagePath)
    {
        $this->imagePath = $imagePath;
    }

    public function handle()
    {
        // Procesa la imagen aquí
    }
}

Para despachar el Job, simplemente usa:

ProcessImage::dispatch($imagePath);

Configura el Sistema de Caché

Laravel ofrece un sistema de caché robusto que puedes usar para mejorar el rendimiento de tu aplicación. Puedes almacenar en caché consultas de base de datos, vistas y otros datos que no cambian con frecuencia.

Para almacenar en caché una consulta de base de datos, puedes hacer lo siguiente:

$posts = Cache::remember('posts', 60, function () {
    return Post::all();
});

Esto almacenará la consulta en caché durante 60 minutos.

Implementa la Autenticación y Autorización

Laravel proporciona un sistema de autenticación y autorización muy completo. Asegúrate de usar las características de autenticación de Laravel, como el registro de usuarios, el inicio de sesión y la recuperación de contraseñas.

Para implementar la autorización, utiliza las políticas y gates que hemos discutido anteriormente. Esto te permitirá gestionar quién puede acceder a qué recursos en tu aplicación de manera efectiva.

Mantén la Seguridad de tu Aplicación

La seguridad es crucial en el desarrollo de aplicaciones web. Asegúrate de seguir las mejores prácticas de seguridad, como:

  • Usar HTTPS: Asegúrate de que tu aplicación esté disponible solo a través de HTTPS.
  • Validar y sanitizar entradas: Siempre valida y sanitiza las entradas del usuario para evitar ataques de inyección SQL y XSS.
  • Usar protección CSRF: Laravel incluye protección CSRF de forma predeterminada, así que asegúrate de que esté habilitada en tus formularios.
  • Limitar intentos de inicio de sesión: Usa el middleware de throttle para limitar los intentos de inicio de sesión y proteger tu aplicación contra ataques de fuerza bruta.

Documenta tu Código

Una buena documentación es fundamental para mantener la calidad del código y facilitar la colaboración en equipo. Utiliza herramientas como PHPDoc para documentar tus clases y métodos. Esto no solo ayuda a otros desarrolladores a comprender tu código, sino que también puede ser útil para ti mismo en el futuro.

Usa Versiones de API

Si estás desarrollando una API, considera implementar versiones de API desde el principio. Esto te permitirá realizar cambios en la API sin romper la compatibilidad con los clientes existentes.

Puedes hacerlo creando diferentes rutas para cada versión de tu API, como:

Route::prefix('api/v1')->group(function () {
    Route::get('/posts', [PostController::class, 'index']);
});

Route::prefix('api/v2')->group(function () {
    Route::get('/posts', [PostV2Controller::class, 'index']);
});

Conclusión

Adoptar estas mejores prácticas y consejos para Laravel en 2025 no solo mejorará la calidad de tu código, sino que también te ayudará a construir aplicaciones más seguras y eficientes. Mantente al día con las actualizaciones de Laravel y la comunidad, y sigue perfeccionando tus habilidades. ¡Feliz codificación!


重试
删除
固定
复制

Comments

Popular posts from this blog

PHP 8.4 Introduces array_find Function: Innovation or Gimmick?

Estrategia de optimización del rendimiento de Laravel: del análisis del código fuente a la práctica real

Se necesitaron 5 días para compilar un conjunto completo de recursos PHP