Tutorial paso a paso para crear una aplicación CRUD con Laravel y PHP
El desarrollo de aplicaciones web es una habilidad fundamental para cualquier programador en la actualidad. En este tutorial, te guiaré paso a paso para que puedas construir una aplicación CRUD (Crear, Leer, Actualizar y Eliminar) usando Laravel, uno de los frameworks PHP más populares y robustos.
Si eres principiante o tienes experiencia intermedia en PHP, este tutorial te ayudará a entender desde la instalación de Laravel hasta la implementación completa de los componentes fundamentales: migraciones, modelos, controladores, rutas y vistas con Blade. Además, te mostraré cómo validar formularios para asegurar la integridad de los datos.
Tabla de contenidos
- Introducción a Laravel y Requisitos
- Instalación y Configuración de Laravel
- Creación de Migraciones y Modelos
- Desarrollo de Controladores y Rutas
- Implementación de Vistas con Blade
- Validación de Formularios en Laravel
- Conclusión y Buenas Prácticas
Introducción a Laravel y Requisitos
Laravel es un framework PHP que sigue el patrón arquitectónico MVC (Modelo-Vista-Controlador) y facilita el desarrollo backend mediante herramientas modernas y eficientes.
Requisitos previos
Antes de comenzar, asegúrate de tener lo siguiente:
- PHP 8.0 o superior instalado
- Composer instalado (gestor de dependencias para PHP)
- Servidor web local (como XAMPP, WAMP, Laragon o Valet)
- Editor de código (VS Code recomendado)
Instalación y Configuración de Laravel
1. Crear un nuevo proyecto Laravel
Abre tu terminal y ejecuta:
1 2 |
composer create-project --prefer-dist laravel/laravel crud-app |
Este comando creará una carpeta llamada crud-app
con un proyecto Laravel completamente configurado.
2. Ingresar al directorio del proyecto
1 2 |
cd crud-app |
3. Configurar la conexión a la base de datos
Laravel utiliza un archivo .env
para gestionar variables de entorno.
Abre .env
y modifica las siguientes líneas según tu configuración de base de datos:
1 2 3 4 5 6 7 |
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=crud_db DB_USERNAME=tu_usuario DB_PASSWORD=tu_contraseña |
Nota: Crea la base de datos
crud_db
en MySQL o en el sistema que uses antes de continuar.
4. Arrancar el servidor local de desarrollo
Ejecuta:
1 2 |
php artisan serve |
Esto levantará el servidor en http://localhost:8000
.
Accede a esta URL en tu navegador para verificar que Laravel está funcionando.
Creación de Migraciones y Modelos
Laravel utiliza migraciones para administrar las tablas de la base de datos y modelos para interactuar con ellas.
Vamos a crear una simple aplicación para manejar tareas.
1. Crear la migración y el modelo
Ejecuta este comando para generar ambos:
1 2 |
php artisan make:model Task -m |
Esto crea:
- El modelo
Task.php
enapp/Models
- La migración para la tabla
tasks
endatabase/migrations
2. Definir los campos en la migración
Abre el archivo de migración creado, algo similar a:
database/migrations/2024_06_01_000000_create_tasks_table.php
Modifícalo así:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<?php use IlluminateDatabaseMigrationsMigration; use IlluminateDatabaseSchemaBlueprint; use IlluminateSupportFacadesSchema; class CreateTasksTable extends Migration { public function up() { Schema::create('tasks', function (Blueprint $table) { $table->id(); // ID autoincrement $table->string('title'); // Título de la tarea $table->text('description')->nullable(); // Descripción opcional $table->boolean('completed')->default(false); // Estado de completado $table->timestamps(); // created_at y updated_at }); } public function down() { Schema::dropIfExists('tasks'); } } |
3. Ejecutar la migración
1 2 |
php artisan migrate |
Esto crea la tabla tasks
en la base de datos.
4. Configurar el modelo
Abre app/Models/Task.php
y asegúrate de que permita la asignación masiva (mass assignment) para los campos que usarás:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?php namespace AppModels; use IlluminateDatabaseEloquentFactoriesHasFactory; use IlluminateDatabaseEloquentModel; class Task extends Model { use HasFactory; // Campos que pueden ser asignados masivamente protected $fillable = [ 'title', 'description', 'completed', ]; } |
Desarrollo de Controladores y Rutas
1. Crear un controlador para gestionar las tareas
1 2 |
php artisan make:controller TaskController --resource |
El parámetro --resource
crea un controlador con métodos predefinidos para CRUD.
2. Definir las rutas en routes/web.php
Abre este archivo y agrega:
1 2 3 4 5 |
use AppHttpControllersTaskController; // Ruta resource para tareas Route::resource('tasks', TaskController::class); |
Esto generará rutas para todas las operaciones CRUD.
3. Implementar métodos en el controlador
Abre app/Http/Controllers/TaskController.php
y modifica para gestionar operaciones básicas:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
<?php namespace AppHttpControllers; use AppModelsTask; use IlluminateHttpRequest; class TaskController extends Controller { // Mostrar listado de tareas public function index() { $tasks = Task::all(); // Obtener todas las tareas return view('tasks.index', compact('tasks')); } // Mostrar formulario para crear public function create() { return view('tasks.create'); } // Almacenar tarea nueva public function store(Request $request) { // Validar datos $request->validate([ 'title' => 'required|max:255', 'description' => 'nullable', ]); // Crear tarea Task::create($request->all()); // Redirigir a listado con mensaje return redirect()->route('tasks.index')->with('success', 'Tarea creada exitosamente'); } // Mostrar formulario para editar tarea public function edit(Task $task) { return view('tasks.edit', compact('task')); } // Actualizar tarea public function update(Request $request, Task $task) { // Validar datos $request->validate([ 'title' => 'required|max:255', 'description' => 'nullable', 'completed' => 'boolean', ]); // Actualizar $task->update($request->all()); return redirect()->route('tasks.index')->with('success', 'Tarea actualizada exitosamente'); } // Eliminar tarea public function destroy(Task $task) { $task->delete(); return redirect()->route('tasks.index')->with('success', 'Tarea eliminada exitosamente'); } } |
Implementación de Vistas con Blade
Laravel usa el motor de plantillas Blade para separar la lógica de presentación.
Creamos las vistas dentro de resources/views/tasks
.
1. Crear un layout base
Crea resources/views/layouts/app.blade.php
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Aplicación CRUD Laravel</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div class="container mt-4"> <h1 class="mb-4">@yield('title')</h1> @if(session('success')) <div class="alert alert-success">{{ session('success') }}</div> @endif @yield('content') </div> </body> </html> |
2. Crear la vista de listado de tareas (index.blade.php
)
resources/views/tasks/index.blade.php
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
@extends('layouts.app') @section('title', 'Listado de Tareas') @section('content') <a href="{{ route('tasks.create') }}" class="btn btn-primary mb-3">Crear nueva tarea</a> @if($tasks->isEmpty()) <p>No hay tareas disponibles.</p> @else <table class="table table-bordered"> <thead> <tr> <th>Título</th> <th>Descripción</th> <th>Completada</th> <th>Acciones</th> </tr> </thead> <tbody> @foreach($tasks as $task) <tr> <td>{{ $task->title }}</td> <td>{{ $task->description }}</td> <td>{{ $task->completed ? 'Sí' : 'No' }}</td> <td> <a href="{{ route('tasks.edit', $task) }}" class="btn btn-sm btn-warning">Editar</a> <form action="{{ route('tasks.destroy', $task) }}" method="POST" style="display:inline-block;"> @csrf @method('DELETE') <button type="submit" class="btn btn-sm btn-danger" onclick="return confirm('¿Seguro que quieres eliminar esta tarea?')">Eliminar</button> </form> </td> </tr> @endforeach </tbody> </table> @endif @endsection |
3. Crear la vista para crear (create.blade.php
)
resources/views/tasks/create.blade.php
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
@extends('layouts.app') @section('title', 'Crear Tarea') @section('content') <form action="{{ route('tasks.store') }}" method="POST"> @csrf <div class="mb-3"> <label for="title" class="form-label">Título</label> <input type="text" name="title" id="title" class="form-control" value="{{ old('title') }}" required> @error('title') <div class="text-danger">{{ $message }}</div> @enderror </div> <div class="mb-3"> <label for="description" class="form-label">Descripción</label> <textarea name="description" id="description" class="form-control">{{ old('description') }}</textarea> @error('description') <div class="text-danger">{{ $message }}</div> @enderror </div> <button type="submit" class="btn btn-success">Guardar</button> <a href="{{ route('tasks.index') }}" class="btn btn-secondary">Cancelar</a> </form> @endsection |
4. Crear la vista para editar (edit.blade.php
)
resources/views/tasks/edit.blade.php
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
@extends('layouts.app') @section('title', 'Editar Tarea') @section('content') <form action="{{ route('tasks.update', $task) }}" method="POST"> @csrf @method('PUT') <div class="mb-3"> <label for="title" class="form-label">Título</label> <input type="text" name="title" id="title" class="form-control" value="{{ old('title', $task->title) }}" required> @error('title') <div class="text-danger">{{ $message }}</div> @enderror </div> <div class="mb-3"> <label for="description" class="form-label">Descripción</label> <textarea name="description" id="description" class="form-control">{{ old('description', $task->description) }}</textarea> @error('description') <div class="text-danger">{{ $message }}</div> @enderror </div> <div class="form-check mb-3"> <input type="checkbox" name="completed" id="completed" class="form-check-input" value="1" {{ $task->completed ? 'checked' : '' }}> <label for="completed" class="form-check-label">Completada</label> </div> <button type="submit" class="btn btn-primary">Actualizar</button> <a href="{{ route('tasks.index') }}" class="btn btn-secondary">Cancelar</a> </form> @endsection |
Validación de Formularios en Laravel
Ya implementamos la validación básica en el controlador dentro de store
y update
.
Laravel proporciona un mensaje de error automático que podemos mostrar en las vistas con la directiva @error
(como se hizo arriba).
Para mejorar la experiencia, siempre valida los datos entrantes para evitar errores y mantener la integridad.
Ejemplo de reglas:
1 2 3 4 5 6 |
$request->validate([ 'title' => 'required|max:255', 'description' => 'nullable', 'completed' => 'boolean', ]); |
Puedes agregar reglas más complejas según tus necesidades.
Conclusión y Buenas Prácticas
En este tutorial hemos creado una aplicación CRUD completa usando Laravel y PHP, ideal para principiantes e intermedios. Vimos cómo:
- Instalar y configurar Laravel
- Crear migraciones y modelos
- Desarrollar controladores y configurar rutas
- Implementar vistas con Blade
- Validar los formularios para mayor seguridad
Buenas prácticas recomendadas
- Utiliza migraciones para mantener un historial claro de cambios en la base de datos.
- Siempre valida entradas del usuario para evitar inconsistencias.
- Separa la lógica dentro de controladores para mantener el código limpio.
- Usa plantillas Blade para mantener la presentación desacoplada del backend.
- Implementa mensajes claros para el usuario tras acciones como crear, actualizar o eliminar.
¿Qué sigue?
Puedes continuar ampliando esta aplicación con:
- Autenticación de usuarios usando Laravel Breeze o Jetstream
- Paginación de resultados
- Búsquedas y filtros
- Uso de componentes Blade para reutilizar fragmentos comunes
¡Ahora es tu turno! Crea tu propia aplicación CRUD personalizada y experimenta con Laravel.
Si te ha gustado este tutorial, no olvides compartirlo y seguir aprendiendo sobre desarrollo backend Laravel y programación PHP para principiantes